Skip to content

线程

引入背景:

  • 进程并发开销大(需拷贝整个地址空间)
  • 进程间通信代价高(需第三方内核空间)
    解决: 在进程地址空间内实现任务并发 → 线程(轻量级进程)

线程定义与特点

定义:

  • 进程内的执行路径(分支)
  • 共享进程地址空间
    类比: 进程如树,主线程(main)为主干,子线程为分支

特点:

  1. 创建开销小: 无需拷贝进程地址空间
  2. 通信高效: 线程间直接共享进程内存
  3. 动态状态:
    • 就绪态 (ready)
    • 运行态 (running)
    • 阻塞态 (blocking)

线程函数原型:

c
typedef void *(*start_routine_t)(void *);  // 函数指针类型  
void *thread_func(void *arg) { /* 线程指令 */ }

线程 API(POSIX Thread)

创建线程
c
#include <pthread.h>  
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,  
                   void *(*start_routine)(void *), void *arg);  
/*  
@描述: 创建新线程  
@thread: 存储线程 ID  
@attr: 线程属性(NULL 为默认)  
@start_routine: 线程执行函数  
@arg: 传递给线程函数的参数  
@return: 成功返回 0,失败返回 -1  
*/
线程退出方式
  1. 函数返回:
    c
    void *thread_func(void *arg) {  
        return NULL;  // 线程结束  
    }
  2. 主动退出:
    c
    void pthread_exit(void *retval);  
    /*  
    @retval: 线程返回值指针  
    */
  3. 被动取消:
    c
    int pthread_cancel(pthread_t thread);  
    /*  
    @thread: 目标线程 ID  
    @return: 成功返回 0  
    */

    取消属性控制:

    c
    int pthread_setcancelstate(int state, int *oldstate);  
    /*  
    @state:  
      PTHREAD_CANCEL_ENABLE(可取消)  
      PTHREAD_CANCEL_DISABLE(不可取消)  
    */

线程资源管理

资源分离属性
  • 分离状态 (detached):
    • 线程结束自动释放资源
    • 设置方式:
      c
      int pthread_detach(pthread_t thread);
  • 非分离状态 (joinable):
    • 需其他线程调用 pthread_join 回收资源
资源回收函数
c
int pthread_join(pthread_t thread, void **retval);  
/*  
@描述: 阻塞等待线程结束并回收资源  
@thread: 目标线程 ID  
@retval: 存储线程返回值的二级指针  
@return: 成功返回 0  
*/
获取线程 ID
c
pthread_t pthread_self(void);  // 返回当前线程 ID

线程同步机制

互斥锁 (pthread_mutex_t)

初始化与销毁:

c
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);  
int pthread_mutex_destroy(pthread_mutex_t *mutex);

attr=NULL 时使用默认属性(初始状态为解锁)

上锁操作 (P 操作):

函数行为
pthread_mutex_lock阻塞等待直到获取锁
pthread_mutex_trylock非阻塞尝试,失败立即返回
pthread_mutex_timedlock限时阻塞等待

解锁操作 (V 操作):

c
int pthread_mutex_unlock(pthread_mutex_t *mutex);

条件变量 (pthread_cond_t)

作用: 表示特定事件/条件,实现线程间同步
初始化与销毁:

c
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);  
int pthread_cond_destroy(pthread_cond_t *cond);

等待条件:

c
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);  
/*  
@描述: 阻塞等待条件触发  
@cond: 条件变量指针  
@mutex: 保护条件变量的互斥锁  
*/  

int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,  
                           const struct timespec *abstime);  // 限时等待

触发条件:

函数行为
pthread_cond_signal唤醒一个等待线程
pthread_cond_broadcast唤醒所有等待线程

生产者-消费者模型

核心逻辑:

  1. 生产者线程: 生成任务存入缓冲区
  2. 消费者线程: 从缓冲区取出任务执行
  3. 同步机制:
    • 互斥锁: 保护缓冲区访问
    • 条件变量:
      • 缓冲区空 → 消费者等待 (pthread_cond_wait)
      • 生产者添加任务 → 触发条件 (pthread_cond_signal)

关键问题:

  • 缓冲区无数据时,消费者应等待而非轮询(避免 CPU 浪费)

作业

实现生产者-消费者模型代码:

  1. 创建生产者线程生成任务
  2. 创建消费者线程执行任务
  3. 使用互斥锁和条件变量同步线程

知识如风,常伴吾身