POSIX标准中的线程管理API(POSIX线程,也称为pthreads)提供了一套用于创建、管理、同步和终止线程的接口。这些接口是多线程编程的核心工具,确保线程之间的正确协作和同步。以下是POSIX线程管理API的详细说明:
1. 线程创建与管理
-
pthread_create()
- 原型:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
- 描述:创建一个新线程,执行
start_routine
函数。线程的执行开始时传递arg
作为参数。 - 参数:
thread
:指向pthread_t
类型的线程标识符。attr
:线程的属性,通常为NULL
使用默认属性。start_routine
:线程执行的函数。arg
:传递给start_routine
的参数。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_join()
- 原型:
int pthread_join(pthread_t thread, void **retval);
- 描述:等待指定线程终止,并获取其退出状态。
- 参数:
thread
:线程标识符,表示要等待的线程。retval
:指向void *
的指针,线程终止时的退出状态。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_detach()
- 原型:
int pthread_detach(pthread_t thread);
- 描述:将线程标记为分离状态,线程结束时资源会被自动回收。
- 参数:
thread
:要设置为分离状态的线程标识符。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_self()
- 原型:
pthread_t pthread_self(void);
- 描述:获取当前线程的线程标识符。
- 返回值:返回当前线程的
pthread_t
标识符。
- 原型:
2. 线程退出
pthread_exit()
- 原型:
void pthread_exit(void *retval);
- 描述:终止调用线程的执行,并返回
retval
作为退出状态。 - 参数:
retval
:线程退出状态,传递给pthread_join
。
- 注意:不会终止整个进程,只会终止当前线程。
- 原型:
3. 互斥锁(Mutex)
-
pthread_mutex_init()
- 原型:
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
- 描述:初始化互斥锁。
- 参数:
mutex
:指向pthread_mutex_t
类型的互斥锁对象。attr
:互斥锁属性,通常为NULL
使用默认属性。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_mutex_lock()
- 原型:
int pthread_mutex_lock(pthread_mutex_t *mutex);
- 描述:锁定互斥锁,阻塞线程直到互斥锁可用。
- 参数:
mutex
:要锁定的互斥锁对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_mutex_unlock()
- 原型:
int pthread_mutex_unlock(pthread_mutex_t *mutex);
- 描述:解锁互斥锁。
- 参数:
mutex
:要解锁的互斥锁对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_mutex_destroy()
- 原型:
int pthread_mutex_destroy(pthread_mutex_t *mutex);
- 描述:销毁互斥锁。
- 参数:
mutex
:要销毁的互斥锁对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
4. 条件变量(Condition Variables)
-
pthread_cond_init()
- 原型:
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
- 描述:初始化条件变量。
- 参数:
cond
:指向pthread_cond_t
类型的条件变量对象。attr
:条件变量属性,通常为NULL
使用默认属性。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_cond_wait()
- 原型:
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
- 描述:等待条件变量的条件满足。线程会释放互斥锁并被阻塞,直到条件变量发出信号。
- 参数:
cond
:要等待的条件变量对象。mutex
:与条件变量相关联的互斥锁。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_cond_signal()
- 原型:
int pthread_cond_signal(pthread_cond_t *cond);
- 描述:唤醒一个等待条件变量的线程。
- 参数:
cond
:要发出信号的条件变量对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_cond_broadcast()
- 原型:
int pthread_cond_broadcast(pthread_cond_t *cond);
- 描述:唤醒所有等待条件变量的线程。
- 参数:
cond
:要发出广播的条件变量对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_cond_destroy()
- 原型:
int pthread_cond_destroy(pthread_cond_t *cond);
- 描述:销毁条件变量。
- 参数:
cond
:要销毁的条件变量对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
5. 线程属性
-
pthread_attr_init()
- 原型:
int pthread_attr_init(pthread_attr_t *attr);
- 描述:初始化线程属性对象。
- 参数:
attr
:指向pthread_attr_t
类型的线程属性对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_attr_destroy()
- 原型:
int pthread_attr_destroy(pthread_attr_t *attr);
- 描述:销毁线程属性对象。
- 参数:
attr
:要销毁的线程属性对象。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_attr_setdetachstate()
- 原型:
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
- 描述:设置线程的分离状态。
- 参数:
attr
:线程属性对象。detachstate
:分离状态,取值可以是PTHREAD_CREATE_JOINABLE
(可等待)或PTHREAD_CREATE_DETACHED
(分离的)。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_attr_getdetachstate()
- 原型:
int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
- 描述:获取线程的分离状态。
- 参数:
attr
:线程属性对象。detachstate
:分离状态的指针,输出参数。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_attr_setstacksize()
- 原型:
int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
- 描述:设置线程栈的大小。
- 参数:
attr
:线程属性对象。stacksize
:栈的大小。
- 返回值:成功返回0,失败返回错误码。
- 原型:
-
pthread_attr_getstacksize()
- 原型:
int pthread_attr_getstacksize(const pthread_attr_t
- 原型:
*attr, size_t *stacksize);
```
- 描述:获取线程栈的大小。
- 参数:
attr
:线程属性对象。stacksize
:输出的栈大小。
- 返回值:成功返回0,失败返回错误码。
这些API接口提供了创建和管理线程、进行线程同步以及处理线程退出的功能。它们是POSIX标准多线程编程的基础,确保了在多线程环境中线程间的协作和同步。
使用POSIX线程管理API的测试例程
这个程序会演示线程创建、属性设置、互斥锁、条件变量以及线程同步等功能。
示例代码
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
// 线程数
#define NUM_THREADS 3
// 互斥锁和条件变量
pthread_mutex_t mutex;
pthread_cond_t cond;
int shared_data = 0;
int ready = 0;
// 线程函数
void *thread_function(void *thread_id) {
int id = *((int *)thread_id);
// 加锁
pthread_mutex_lock(&mutex);
// 线程等待条件变量
while (ready == 0) {
pthread_cond_wait(&cond, &mutex);
}
// 处理共享数据
shared_data += id;
printf("Thread %d processed shared_data = %d\n", id, shared_data);
// 解锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
int thread_ids[NUM_THREADS];
int rc;
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
// 初始化线程属性
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
// 创建线程
for (int i = 0; i < NUM_THREADS; i++) {
thread_ids[i] = i + 1;
rc = pthread_create(&threads[i], &attr, thread_function, (void *)&thread_ids[i]);
if (rc) {
printf("Error: Unable to create thread %d, %d\n", i, rc);
exit(-1);
}
}
// 主线程处理一些任务
printf("Main thread is doing some work...\n");
sleep(2); // 模拟工作
// 修改共享数据并通知线程
pthread_mutex_lock(&mutex);
ready = 1;
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
// 等待所有线程完成
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
// 清理
pthread_attr_destroy(&attr);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
printf("Main thread finished.\n");
return 0;
}
编译和运行
-
保存代码:将上述代码保存为
thread_test.c
文件。 -
编译:
使用gcc
编译器编译代码。-pthread
选项用于链接线程库。gcc -o thread_test thread_test.c -pthread
-
运行:
执行编译生成的可执行文件。./thread_test
输出结果
Main thread is doing some work...
Thread 1 processed shared_data = 1
Thread 2 processed shared_data = 3
Thread 3 processed shared_data = 6
Main thread finished.
输出分析
-
主线程工作:
- 主线程创建了多个线程,然后模拟了一些工作,等待时间由
sleep(2)
产生。这个等待时间可以模拟主线程在创建线程后的工作。
- 主线程创建了多个线程,然后模拟了一些工作,等待时间由
-
线程处理共享数据:
- 每个线程在获取到互斥锁后,检查条件变量是否满足,如果不满足则等待。主线程在完成工作后,修改共享数据并通过条件变量通知所有线程。
- 所有线程在收到通知后继续执行,处理共享数据并输出结果。
-
互斥锁和条件变量:
- 互斥锁用于保护共享数据的访问,确保在任意时刻只有一个线程可以访问和修改
shared_data
。 - 条件变量用于线程同步,确保线程在条件满足之前不会继续执行。
- 互斥锁用于保护共享数据的访问,确保在任意时刻只有一个线程可以访问和修改
-
线程属性:
- 设置线程属性为
PTHREAD_CREATE_JOINABLE
,确保主线程可以等待每个线程完成。pthread_attr_init()
和pthread_attr_setdetachstate()
用于初始化和设置线程属性。
- 设置线程属性为
-
清理:
- 主线程在所有线程完成后,销毁线程属性、互斥锁和条件变量,确保资源得到正确释放。