一、多线程基础概念
1.1 进程与线程的区别
1.2 多线程的优点
1.3 多线程的适用场景
二、POSIX线程标准与库
2.1 遵循标准
2.2 头文件与编译
#include<pthread.h>
编译链接选项:-lpthread
三、线程的生命周期
| |
|---|
| 新建(New) | |
| 就绪(Ready) | |
| 运行(Running) | |
| 阻塞(Blocked) | |
| 终止(Terminated) | |
3.1 状态转换关系
新建 → 就绪 → 运行 → 终止 ↓ ↑ 阻塞 ←┘
四、线程的基本操作
4.1 线程创建
函数原型:
intpthread_create(pthread_t *thread,constpthread_attr_t *attr,void *(*start_routine)(void*),void *arg);
| |
|---|
thread | |
attr | |
start_routine | |
arg | |
返回值: 0表示成功,非0表示错误码
4.2 线程等待(Join)
函数原型:
intpthread_join(pthread_t thread, void **retval);
作用: 阻塞调用线程,直到指定线程结束
4.3 线程分离(Detach)
函数原型:
intpthread_detach(pthread_t thread);
| pthread_join | pthread_detach |
|---|
| | |
| | |
| | |
| | |
4.4 线程退出
| | |
|---|
| return | |
| pthread_exit(void *retval) | |
| pthread_cancel(pthread_t thread) | |
| | |
pthread_exit函数原型:
voidpthread_exit(void *retval);
4.5 线程取消
函数原型:
intpthread_cancel(pthread_t thread);
取消点: 线程在执行某些函数时会检查取消请求,如read()、write()、sleep()等
4.6 线程清理(Cleanup)
注册清理函数:
voidpthread_cleanup_push(void (*routine)(void*), void *arg);voidpthread_cleanup_pop(int execute);
使用场景: 线程被取消或调用pthread_exit时,执行资源释放等清理工作
4.7 获取线程ID
函数原型:
pthread_tpthread_self(void);
作用: 返回调用线程的线程标识符
五、线程属性操作
5.1 属性初始化与销毁
intpthread_attr_init(pthread_attr_t *attr);intpthread_attr_destroy(pthread_attr_t *attr);
5.2 分离属性(Detach State)
intpthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);intpthread_attr_getdetachstate(constpthread_attr_t *attr, int *detachstate);
| |
|---|
PTHREAD_CREATE_JOINABLE | |
PTHREAD_CREATE_DETACHED | |
5.3 栈大小属性(Stack Size)
intpthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);intpthread_attr_getstacksize(constpthread_attr_t *attr, size_t *stacksize);
作用: 设置/获取线程栈的大小,防止栈溢出或优化内存使用
5.4 调度属性
5.4.1 设置/获取调度参数
intpthread_setschedparam(pthread_t thread, int policy, const struct sched_param *param);intpthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
| |
|---|
SCHED_FIFO | |
SCHED_RR | |
SCHED_OTHER | |
sched_param结构体:
structsched_param {int sched_priority; // 调度优先级};
5.5 绑定属性(Contention Scope)
intpthread_attr_setscope(pthread_attr_t *attr, int scope);intpthread_attr_getscope(constpthread_attr_t *attr, int *scope);
| |
|---|
PTHREAD_SCOPE_SYSTEM | |
PTHREAD_SCOPE_PROCESS | |
六、线程同步机制
6.1 互斥锁(Mutex)
6.1.1 互斥锁的基本概念
6.1.2 互斥锁操作函数
| | |
|---|
| 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_trylock(pthread_mutex_t *mutex) | |
| int pthread_mutex_unlock(pthread_mutex_t *mutex) | |
6.1.3 互斥锁使用步骤
定义锁 → 初始化锁 → 加锁 → 访问临界区 → 解锁 → 销毁锁
6.1.4 锁的粒度
6.1.5 互斥锁使用示例
#include<pthread.h>#include<stdio.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;int counter = 0;void* increment(void* arg){ pthread_mutex_lock(&mutex); // 加锁for (int i = 0; i < 10000; i++) { counter++; } pthread_mutex_unlock(&mutex); // 解锁returnNULL;}intmain(){pthread_t t1, t2; pthread_create(&t1, NULL, increment, NULL); pthread_create(&t2, NULL, increment, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL);printf("Final counter: %d\n", counter); pthread_mutex_destroy(&mutex);return0;}
6.2 条件变量(Condition Variable)
6.2.1 基本概念
6.2.2 条件变量操作函数
| | |
|---|
| int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr) | |
| int pthread_cond_destroy(pthread_cond_t *cond) | |
| int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) | |
| int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) | |
| int pthread_cond_signal(pthread_cond_t *cond) | |
| int pthread_cond_broadcast(pthread_cond_t *cond) | |
6.2.3 pthread_cond_wait的内部机制
6.2.4 signal与broadcast的区别
| | |
|---|
pthread_cond_signal | | |
pthread_cond_broadcast | | |
6.2.5 条件变量使用步骤
初始化条件变量和互斥锁 ↓线程A:加锁 → 检查条件 → 条件不满足 → cond_wait等待 ↓线程B:加锁 → 修改条件 → cond_signal/broadcast通知 → 解锁 ↓线程A被唤醒 → 重新加锁 → 继续执行 → 解锁 ↓销毁条件变量和互斥锁
6.3 信号量(Semaphore)
6.3.1 基本概念
6.3.2 信号量操作函数
| | |
|---|
| int sem_init(sem_t *sem, int pshared, unsigned int value) | |
| int sem_wait(sem_t *sem) | |
| int sem_trywait(sem_t *sem) | |
| int sem_post(sem_t *sem) | |
| int sem_getvalue(sem_t *sem, int *sval) | |
| int sem_destroy(sem_t *sem) | |
sem_init参数说明:
6.3.3 信号量使用步骤
初始化信号量(设置初始值) ↓sem_wait获取信号量(P操作) ↓访问共享资源 ↓sem_post释放信号量(V操作) ↓销毁信号量
6.3.4 用信号量实现互斥
#include<pthread.h>#include<semaphore.h>#include<stdio.h>sem_t mutex;int counter = 0;void* increment(void* arg){ sem_wait(&mutex); // P操作,获取信号量 counter++;printf("Counter: %d\n", counter); sem_post(&mutex); // V操作,释放信号量returnNULL;}intmain(){pthread_t t1, t2; sem_init(&mutex, 0, 1); // 初始值为1,实现互斥 pthread_create(&t1, NULL, increment, NULL); pthread_create(&t2, NULL, increment, NULL); pthread_join(t1, NULL); pthread_join(t2, NULL); sem_destroy(&mutex);return0;}
七、经典同步模型:生产者消费者模型
7.1 模型说明
7.2 同步要点
7.3 完整代码示例
#include<pthread.h>#include<stdio.h>#include<unistd.h>#define BUFFER_SIZE 5// 共享缓冲区int buffer[BUFFER_SIZE];int count = 0; // 当前产品数量int in = 0; // 生产者放入位置int out = 0; // 消费者取出位置// 同步机制pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;pthread_cond_t not_full = PTHREAD_COND_INITIALIZER; // 缓冲区不满pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER; // 缓冲区不空// 生产者函数voidproduce(int item){ pthread_mutex_lock(&mutex);// 缓冲区满,等待while (count == BUFFER_SIZE) {printf("Buffer full, producer waiting...\n"); pthread_cond_wait(¬_full, &mutex); }// 放入产品 buffer[in] = item; in = (in + 1) % BUFFER_SIZE; count++;printf("Produced: %d, count=%d\n", item, count);// 通知消费者 pthread_cond_signal(¬_empty); pthread_mutex_unlock(&mutex);}// 消费者函数intconsume(){ pthread_mutex_lock(&mutex);// 缓冲区空,等待while (count == 0) {printf("Buffer empty, consumer waiting...\n"); pthread_cond_wait(¬_empty, &mutex); }// 取出产品int item = buffer[out]; out = (out + 1) % BUFFER_SIZE; count--;printf("Consumed: %d, count=%d\n", item, count);// 通知生产者 pthread_cond_signal(¬_full); pthread_mutex_unlock(&mutex);return item;}// 生产者线程void* producer_thread(void* arg){for (int i = 0; i < 10; i++) { produce(i); sleep(1); }returnNULL;}// 消费者线程void* consumer_thread(void* arg){for (int i = 0; i < 10; i++) { consume(); sleep(1); }returnNULL;}intmain(){pthread_t prod, cons; pthread_create(&prod, NULL, producer_thread, NULL); pthread_create(&cons, NULL, consumer_thread, NULL); pthread_join(prod, NULL); pthread_join(cons, NULL);// 清理资源 pthread_mutex_destroy(&mutex); pthread_cond_destroy(¬_full); pthread_cond_destroy(¬_empty);return0;}
八、高级同步机制
8.1 读写锁(Read-Write Lock)
函数原型:
intpthread_rwlock_init(pthread_rwlock_t *rwlock, constpthread_rwlockattr_t *attr);intpthread_rwlock_rdlock(pthread_rwlock_t *rwlock); // 获取读锁intpthread_rwlock_wrlock(pthread_rwlock_t *rwlock); // 获取写锁intpthread_rwlock_unlock(pthread_rwlock_t *rwlock); // 释放锁intpthread_rwlock_destroy(pthread_rwlock_t *rwlock);
8.2 自旋锁(Spin Lock)
函数原型:
intpthread_spin_init(pthread_spinlock_t *lock, int pshared);intpthread_spin_lock(pthread_spinlock_t *lock);intpthread_spin_trylock(pthread_spinlock_t *lock);intpthread_spin_unlock(pthread_spinlock_t *lock);intpthread_spin_destroy(pthread_spinlock_t *lock);
8.3 屏障(Barrier)
函数原型:
intpthread_barrier_init(pthread_barrier_t *barrier, constpthread_barrierattr_t *attr, unsignedint count);intpthread_barrier_wait(pthread_barrier_t *barrier);intpthread_barrier_destroy(pthread_barrier_t *barrier);
九、线程池
9.1 概念
9.2 优点
9.3 核心组件
9.4 适用场景
十、多线程常见问题与解决方案
10.1 竞态条件(Race Condition)
10.2 死锁(Deadlock)
10.3 活锁(Livelock)
10.4 饥饿(Starvation)
十一、实际应用场景
11.1 大文件断点续传
11.2 多文件同时读写
11.3 高并发服务器
十二、多线程编程最佳实践