一、Linux 中线程的核心概念
首先,先明确 Linux 下线程的特殊之处:
- 在 Linux 内核层面,并没有真正意义上的 "线程" 结构 ,Linux 把所有执行流(进程 / 线程)都统一称为 轻量级进程(LWP, Light Weight Process)。
- 我们平时说的 "线程",本质是共享同一地址空间的多个 LWP(共享内存、文件描述符、信号处理等资源)。
- 线程的优势:创建 / 切换开销远小于进程,通信成本极低(直接读写全局变量),但稳定性差(一个线程崩溃会导致整个进程退出)。
二、Linux 线程核心函数(pthread 库)
Linux 操作线程的函数都在 pthread 库中,编译时必须加 -lpthread 链接库
(例如:gcc test.c -o test -lpthread)。
1. 线程创建:pthread_create()
功能:创建一个新的线程,执行指定的函数。
函数原型:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
参数解释:
thread:输出参数,保存新创建线程的 ID (pthread_t类型)。attr:线程属性(优先级、栈大小等),一般传NULL使用默认属性。start_routine:线程要执行的函数指针(函数格式必须是void* 函数名(void*))。arg:传给线程函数的参数(无类型指针,可传任意数据,需自己做类型转换)。
返回值:成功返回 0,失败返回错误码(Linux 系统调用一般返回 -1,但 pthread 函数直接返回错误码)。
2. 线程等待:pthread_join()
功能 :阻塞等待指定线程退出,并回收线程资源(类似进程的 wait()),避免 "僵尸线程"。
函数原型:
int pthread_join(pthread_t thread, void **retval);
参数解释:
thread:要等待的线程 ID。retval:输出参数,保存线程退出时的返回值(即start_routine函数的返回值),不需要则传NULL。
返回值:成功返回 0,失败返回错误码。
3. 线程退出:pthread_exit()
功能 :主动终止当前线程,且不会影响同进程的其他线程(区别于 exit(),exit() 会终止整个进程)。
函数原型:
void pthread_exit(void *retval);
参数 :retval:线程退出的返回值,可被 pthread_join() 获取。
4. 线程分离:pthread_detach()
功能 :将线程设置为 "分离态",线程退出时会自动回收资源,无需主线程调用 pthread_join()。适用场景:主线程不关心子线程的退出状态,不想阻塞等待。
函数原型:
int pthread_detach(pthread_t thread);
5. 获取线程 ID:pthread_self()
功能:获取当前线程的 ID(区别于内核的 LWP ID)。
函数原型:
pthread_t pthread_self(void);
6. 线程取消:pthread_cancel()
功能:向指定线程发送 "取消请求",让线程退出(需线程处于可取消状态)。
函数原型:
int pthread_cancel(pthread_t thread);
三、线程同步
线程共享进程资源,多线程操作同一变量时会出现 "竞态条件"(数据错乱),必须通过同步机制解决,核心函数:
- 互斥锁(pthread_mutex_t) :
pthread_mutex_init():初始化互斥锁pthread_mutex_lock():加锁(阻塞)pthread_mutex_unlock():解锁pthread_mutex_destroy():销毁互斥锁
- 条件变量(pthread_cond_t):解决 "等待 - 唤醒" 场景(如生产者 - 消费者模型)。
四、总结
- Linux 线程本质:是共享地址空间的轻量级进程(LWP),无独立资源,仅共享进程资源。
- 核心函数 :
- 创建:
pthread_create()(编译加-lpthread) - 等待:
pthread_join()(回收资源,避免僵尸线程) - 退出:
pthread_exit()(仅终止当前线程) - 同步:互斥锁(
pthread_mutex_*)解决多线程数据竞争。
- 创建:
- 关键注意点:线程崩溃会导致整个进程退出,多线程操作共享资源必须加同步锁。