pthread
是 POSIX 线程库(POSIX Threads)的缩写,用于实现多线程编程。pthread
库适用于 Linux 和其他 POSIX 系统,提供线程创建、同步、管理等功能。以下是一个详细的 pthread
使用教程。
1. 基本概念
- 线程:一个线程是进程中的一个执行单元,拥有自己的栈空间和寄存器,但共享同一进程的内存空间。
- 主线程和子线程:通常,创建线程的线程称为主线程,被创建的线程称为子线程。
2. 使用pthread
的基本流程
2.1 包含头文件
在使用 pthread
时,首先要包含头文件:
#include <pthread.h>
2.2 编译链接 pthread
库
编译时需链接 pthread
库:
gcc -o my_program my_program.c -lpthread
3. 创建线程
3.1 pthread_create
pthread_create
函数用于创建新线程,语法如下:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
thread
:指向线程标识符的指针,创建成功后将存储新线程的 ID。attr
:线程属性,可设置为NULL
表示使用默认属性。start_routine
:线程的执行函数,必须返回void*
类型并接受void*
类型的参数。arg
:传递给线程函数的参数。
示例:创建一个简单线程
#include <stdio.h>
#include <pthread.h>
void* thread_function(void* arg) {
printf("Hello from thread!\n");
return NULL;
}
int main() {
pthread_t thread_id;
pthread_create(&thread_id, NULL, thread_function, NULL);
pthread_join(thread_id, NULL); // 等待线程完成
return 0;
}
4. 等待线程完成
pthread_join
用于等待线程执行完毕,阻塞主线程直至指定线程完成。
int pthread_join(pthread_t thread, void **retval);
thread
:要等待的线程标识符。retval
:用于存储线程的返回值,可设为NULL
表示不关心返回值。
示例:等待线程结束
pthread_join(thread_id, NULL);
5. 线程传递参数
可以通过指针将参数传递给线程函数:
#include <stdio.h>
#include <pthread.h>
void* thread_function(void* arg) {
int* num = (int*)arg;
printf("Thread received: %d\n", *num);
return NULL;
}
int main() {
pthread_t thread_id;
int value = 42;
pthread_create(&thread_id, NULL, thread_function, &value);
pthread_join(thread_id, NULL);
return 0;
}
6. 线程同步
pthread
提供多种同步机制以避免线程间的竞争,如 互斥锁、条件变量 等。
6.1 互斥锁(Mutex)
互斥锁用于保护共享资源,保证同一时刻只有一个线程访问。
- 初始化互斥锁:
pthread_mutex_init
- 加锁:
pthread_mutex_lock
- 解锁:
pthread_mutex_unlock
- 销毁:
pthread_mutex_destroy
示例:互斥锁保护共享资源
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t lock;
void* thread_function(void* arg) {
pthread_mutex_lock(&lock);
counter++;
printf("Counter: %d\n", counter);
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_mutex_init(&lock, NULL);
pthread_create(&thread1, NULL, thread_function, NULL);
pthread_create(&thread2, NULL, thread_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_mutex_destroy(&lock);
return 0;
}
6.2 条件变量(Condition Variable)
条件变量允许线程在满足特定条件时继续执行,用于线程间通信。
- 初始化条件变量:
pthread_cond_init
- 等待条件变量:
pthread_cond_wait
- 发送信号:
pthread_cond_signal
或pthread_cond_broadcast
- 销毁条件变量:
pthread_cond_destroy
示例:条件变量实现线程同步
#include <stdio.h>
#include <pthread.h>
int ready = 0;
pthread_mutex_t lock;
pthread_cond_t cond;
void* wait_function(void* arg) {
pthread_mutex_lock(&lock);
while (!ready) {
pthread_cond_wait(&cond, &lock);
}
printf("Condition met, thread proceeding.\n");
pthread_mutex_unlock(&lock);
return NULL;
}
void* signal_function(void* arg) {
pthread_mutex_lock(&lock);
ready = 1;
pthread_cond_signal(&cond); // 通知等待线程
pthread_mutex_unlock(&lock);
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_mutex_init(&lock, NULL);
pthread_cond_init(&cond, NULL);
pthread_create(&thread1, NULL, wait_function, NULL);
pthread_create(&thread2, NULL, signal_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
return 0;
}
7. 线程属性
pthread_attr_t
用于设置线程属性,例如分离状态、栈大小、调度策略等。
7.1 设置分离状态
分离状态使线程在终止后自动释放资源,不需要 pthread_join
等待线程完成。
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 设置分离状态
pthread_create(&thread_id, &attr, thread_function, NULL);
pthread_attr_destroy(&attr);
8. 线程取消
可以使用 pthread_cancel
取消正在运行的线程,并控制取消行为:
int pthread_cancel(pthread_t thread);
取消请求不会立即生效,取决于线程的取消状态和类型。线程可通过 pthread_setcancelstate
设置是否响应取消请求,或通过 pthread_setcanceltype
控制取消点。
9. 错误处理
线程函数通常返回 0 表示成功,其他值表示错误。可以使用 perror
或 strerror
打印错误信息。
总结
pthread
是 C 语言中强大的多线程编程库。