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 ) |
總結
核心原則:共享資源必須同步(互斥鎖、條件變量)。
性能優化:減少鎖粒度,優先使用讀寫鎖。