C/C++多线程编程:POSIX线程库(pthread)
1. 线程创建与基本执行
核心函数:pthread_create
功能:创建新线程并执行指定函数。
参数说明:
pthread_t *thread
:存储新线程ID的指针const pthread_attr_t *attr
:线程属性(通常为NULL
)void *(*start_routine) (void *)
:线程入口函数void *arg
:传递给线程函数的参数
代码示例:
#include <stdio.h>
#include <pthread.h>
// 线程执行函数
void* thread_func(void* arg) {
int* num = (int*)arg;
printf("子线程ID: %lu, 参数: %d\n", pthread_self(), *num);
return NULL;
}
int main() {
pthread_t tid;
int arg_value = 42;
// 创建线程
if (pthread_create(&tid, NULL, thread_func, &arg_value) != 0) {
perror("线程创建失败");
return 1;
}
// 等待线程结束
pthread_join(tid, NULL);
printf("主线程结束\n");
return 0;
}
关键点:
- 线程函数必须为
void*
返回类型,参数为void*
(可传递任意类型数据) pthread_join
用于阻塞主线程,确保子线程执行完毕
2. 线程同步:互斥锁(Mutex)
核心函数:pthread_mutex_init
、pthread_mutex_lock
、pthread_mutex_unlock
作用:保护共享资源,防止数据竞争。
代码示例:
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex;
int shared_counter = 0;
void* increment_counter(void* arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&mutex);
shared_counter++;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&mutex, NULL);
pthread_create(&t1, NULL, increment_counter, NULL);
pthread_create(&t2, NULL, increment_counter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("最终计数: %d\n", shared_counter); // 应为200000
pthread_mutex_destroy(&mutex);
return 0;
}
关键点:
- 互斥锁需先初始化(
pthread_mutex_init
)再使用 - 加锁/解锁必须成对出现,否则会导致死锁或数据不一致
3. 线程同步:条件变量(Condition Variable)
核心函数:pthread_cond_wait
、pthread_cond_signal
作用:实现线程间的事件通知机制。
代码示例(生产者-消费者模型):
#include <stdio.h>
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int buffer = 0; // 共享缓冲区
void* producer(void* arg) {
pthread_mutex_lock(&mutex);
buffer = 1; // 生产数据
printf("生产者已生产数据\n");
pthread_cond_signal(&cond); // 通知消费者
pthread_mutex_unlock(&mutex);
return NULL;
}
void* consumer(void* arg) {
pthread_mutex_lock(&mutex);
while (buffer == 0) { // 等待数据
pthread_cond_wait(&cond, &mutex); // 自动释放锁并等待
}
printf("消费者收到数据: %d\n", buffer);
buffer = 0; // 消费数据
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t prod, cons;
pthread_create(&prod, NULL, producer, NULL);
pthread_create(&cons, NULL, consumer, NULL);
pthread_join(prod, NULL);
pthread_join(cons, NULL);
return 0;
}
关键点:
pthread_cond_wait
会自动释放锁并进入等待,被唤醒后重新获得锁- 必须配合互斥锁使用,避免条件判断时的竞态条件
4. 线程属性设置
常用属性:
- 分离状态:通过
pthread_attr_setdetachstate
设置线程为分离状态(PTHREAD_CREATE_DETACHED
),无需pthread_join
- 栈大小:使用
pthread_attr_setstacksize
自定义线程栈大小
示例代码:
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&tid, &attr, thread_func, NULL);
pthread_attr_destroy(&attr);
5. 编译与运行
编译命令:
gcc program.c -o program -lpthread
注意事项:
- 必须添加
-lpthread
链接POSIX线程库 - 使用
-pthread
参数可兼容不同平台(推荐)
总结与最佳实践
- 资源管理:始终初始化/销毁互斥锁、条件变量等资源
- 错误检查:检查
pthread_create
等函数的返回值 - 避免死锁:确保锁的获取顺序一致,必要时使用
pthread_mutex_trylock
- 性能优化:减少锁的粒度,优先考虑无锁数据结构(如原子操作)
以上步骤便是POSIX线程库的核心用法。实际开发中可结合Valgrind或TSAN工具检测线程安全问题。