1. 线程基础
(1) 线程创建与终止
#include <pthread.h>
// 创建线程
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine)(void*), void *arg);
// 终止当前线程
void pthread_exit(void *retval);
// 等待线程结束
int pthread_join(pthread_t thread, void **retval);
// 分离线程(不可被join)
int pthread_detach(pthread_t thread);
示例:
void* task(void *arg) {printf("Thread running\n");pthread_exit(NULL); } pthread_t tid; pthread_create(&tid, NULL, task, NULL); pthread_join(tid, NULL);
(2) 线程ID与比较
pthread_t tid = pthread_self(); // 获取自身线程ID
int equal = pthread_equal(tid1, tid2); // 比较线程ID
2. 线程同步机制
(1) 互斥锁(Mutex)
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 静态初始化
// 动态初始化/销毁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
// 加锁/解锁
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
int pthread_mutex_trylock(pthread_mutex_t *mutex); // 非阻塞
示例:
pthread_mutex_lock(&mutex); shared_data++; pthread_mutex_unlock(&mutex);
(2) 条件变量(Condition Variable)
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); // 等待条件
int pthread_cond_signal(pthread_cond_t *cond); // 唤醒一个线程
int pthread_cond_broadcast(pthread_cond_t *cond); // 唤醒所有线程
典型模式:
pthread_mutex_lock(&mutex); while (!condition) {pthread_cond_wait(&cond, &mutex); } // 操作共享数据 pthread_mutex_unlock(&mutex);
(3) 读写锁(Read-Write Lock)
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); // 读锁
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); // 写锁
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
3. 线程属性控制
(1) 线程属性
pthread_attr_t attr;
pthread_attr_init(&attr);
// 设置分离状态
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// 设置栈大小
pthread_attr_setstacksize(&attr, 1024 * 1024); // 1MB
// 使用属性创建线程
pthread_create(&tid, &attr, task, NULL);
pthread_attr_destroy(&attr);
(2) 调度策略与优先级
struct sched_param param;
param.sched_priority = 50; // 优先级(1~99)
// 设置调度策略(需root权限)
pthread_setschedparam(tid, SCHED_FIFO, ¶m);
// 获取当前策略
int policy;
pthread_getschedparam(tid, &policy, ¶m);
4. 线程局部存储(TLS)
// 创建线程局部变量键
pthread_key_t key;
pthread_key_create(&key, NULL);
// 设置/获取线程局部值
void *value = malloc(100);
pthread_setspecific(key, value);
void *data = pthread_getspecific(key);
5. 其他关键函数
函数 | 用途 |
---|---|
pthread_cancel(tid) | 取消目标线程(需线程设置为可取消状态)。 |
pthread_testcancel() | 显式插入取消点。 |
pthread_setcancelstate() | 设置线程取消状态(PTHREAD_CANCEL_ENABLE/DISABLE )。 |
pthread_once() | 确保某函数只执行一次(用于初始化)。 |
6. 常见问题与陷阱
(1) 线程安全函数
非线程安全函数:如
strtok
、localtime
,需使用线程安全版本(strtok_r
、localtime_r
)。
(2) 死锁预防
加锁顺序一致:多个锁按固定顺序获取。
避免锁嵌套:尽量缩短临界区范围。
(3) 资源清理
分离线程:若不需要
pthread_join
,应显式pthread_detach
避免资源泄漏。互斥锁销毁:动态初始化的锁必须
pthread_mutex_destroy
。
7. 调试工具
工具 | 用途 |
---|---|
valgrind --tool=helgrind | 检测数据竞争和死锁。 |
gdb | 调试多线程程序(info threads 、thread <id> )。 |
strace -f | 跟踪线程的系统调用。 |
8. 与C++的对比
特性 | pthread (C) | std::thread (C++11) |
---|---|---|
抽象级别 | 底层(显式管理) | 高层(RAII封装) |
错误处理 | 返回错误码 | 抛出异常 |
跨平台性 | Unix-like 系统 | 跨平台 |
锁类型 | 需手动初始化/销毁 | 自动管理(std::mutex 、std::lock_guard ) |
总结
核心原则:共享资源必须同步(互斥锁、条件变量)。
性能优化:减少锁粒度,优先使用读写锁。