pthread_create & pthread_join
pthread_create
和 pthread_join
是 POSIX 线程(pthreads)编程中用于创建线程和等待线程结束的两个常用函数。它们定义在 <pthread.h>
头文件中,主要用于多线程并发编程。
一、pthread_create
用于创建一个新线程,并让其执行指定的函数。
函数原型:
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
参数说明:
pthread_t *thread
:指向线程 ID 的指针,创建成功后可以通过它操作线程。const pthread_attr_t *attr
:线程属性,一般传NULL
表示使用默认属性。void *(*start_routine)(void *)
:线程将执行的函数指针。void *arg
:传递给start_routine
函数的参数,可以传NULL
。
返回值:
- 成功返回
0
; - 失败返回错误码(不是通过
errno
设置)。
示例:
#include
#include
void* thread_func(void* arg) {
printf("Hello from thread! arg = %d\n", *(int*)arg);
return NULL;
}
int main() {
pthread_t tid;
int val = 42;
if (pthread_create(&tid, NULL, thread_func, &val) != 0) {
perror("pthread_create failed");
return 1;
}
pthread_join(tid, NULL);
return 0;
}
二、pthread_join
用于阻塞等待一个线程结束,并可获取线程的返回值。
函数原型:
int pthread_join(pthread_t thread, void **retval);
参数说明:
pthread_t thread
:目标线程 ID。void **retval
:用于接收目标线程返回值的指针。如果不关心返回值,可以传NULL
。
返回值:
- 成功返回
0
; - 失败返回错误码。
注意事项:
- 如果多次
pthread_join
同一线程,会导致未定义行为; - 被
join
的线程必须是可连接的(joinable),默认就是。如果设置为 detached(分离状态),则不能再 join。
三、总结:使用流程
pthread_t tid;
pthread_create(&tid, NULL, func, arg); // 创建线程
pthread_join(tid, NULL); // 等待线程结束
E.G. B
实现一个有两个线程的程序。每个将自己的ID输出10次,要求输出顺序必须
是线程1,线程2,线程1,线程2,线程1,线程2…。
#include <pthread.h>
#include <iostream>
using namespace std;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int turn = 0;
void* func0(void* arg) {
for(int i = 0; i < 10; i ++) {
pthread_mutex_lock(&mutex);
while(turn != 0) {
pthread_cond_wait(&cond, &mutex);
}
cout << "Thread 1: pthread_self = " << pthread_self() << endl;
turn = 1;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
return nullptr;
}
void* func1(void *arg) {
for(int i = 0; i < 10; i ++) {
pthread_mutex_lock(&mutex);
while(turn != 1) {
pthread_cond_wait(&cond, &mutex);
}
cout << "Thread 2: pthread_self = " << pthread_self() << endl;
turn = 0;
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);
}
return nullptr;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, nullptr, func0, nullptr);
pthread_create(&t2, nullptr, func1, nullptr);
pthread_join(t1, nullptr);
pthread_join(t2, nullptr);
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
return 0;
}