【Linux】pthread学习笔记

发布于:2025-07-30 ⋅ 阅读:(13) ⋅ 点赞:(0)

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, &param);
// 获取当前策略
int policy;
pthread_getschedparam(tid, &policy, &param);

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) 线程安全函数
  • 非线程安全函数:如 strtoklocaltime,需使用线程安全版本(strtok_rlocaltime_r)。

(2) 死锁预防
  • 加锁顺序一致:多个锁按固定顺序获取。

  • 避免锁嵌套:尽量缩短临界区范围。

(3) 资源清理
  • 分离线程:若不需要 pthread_join,应显式 pthread_detach 避免资源泄漏。

  • 互斥锁销毁:动态初始化的锁必须 pthread_mutex_destroy


7. 调试工具

工具 用途
valgrind --tool=helgrind 检测数据竞争和死锁。
gdb 调试多线程程序(info threadsthread <id>)。
strace -f 跟踪线程的系统调用。

8. 与C++的对比

特性 pthread (C) std::thread (C++11)
抽象级别 底层(显式管理) 高层(RAII封装)
错误处理 返回错误码 抛出异常
跨平台性 Unix-like 系统 跨平台
锁类型 需手动初始化/销毁 自动管理(std::mutexstd::lock_guard

总结

  • 核心原则:共享资源必须同步(互斥锁、条件变量)。

  • 性能优化:减少锁粒度,优先使用读写锁。


网站公告

今日签到

点亮在社区的每一天
去签到