在C++中,pthread_create
和 pthread_join
是 POSIX 线程库(pthread
)的一部分,用于创建和管理线程。pthread_create
用于创建一个新的线程,而 pthread_join
用于等待一个线程的执行完成,从而实现线程同步与控制。
基本步骤
- 使用
pthread_create
函数创建一个线程。 - 线程的工作由一个线程函数来完成,该函数的签名必须是
void* threadFunc(void* arg)
。 - 使用
pthread_join
函数等待线程执行完成,并获取线程的退出状态。
以下是如何在C++中使用 pthread_create
和 pthread_join
来创建线程并等待其完成的示例:
示例代码
#include <iostream>
#include <pthread.h> // POSIX 线程库头文件
#include <unistd.h> // sleep 函数
// 线程执行的函数
void* threadFunc(void* arg) {
int* id = static_cast<int*>(arg); // 传入的参数类型转换
std::cout << "Thread " << *id << " is running." << std::endl;
sleep(2); // 模拟线程工作
std::cout << "Thread " << *id << " has finished." << std::endl;
return nullptr;
}
int main() {
const int numThreads = 3;
pthread_t threads[numThreads]; // 保存线程ID
int threadArgs[numThreads]; // 线程的参数
// 创建多个线程
for (int i = 0; i < numThreads; ++i) {
threadArgs[i] = i + 1; // 为每个线程传递不同的参数
if (pthread_create(&threads[i], nullptr, threadFunc, &threadArgs[i]) != 0) {
std::cerr << "Error creating thread " << i + 1 << std::endl;
return 1;
}
}
// 等待所有线程完成
for (int i = 0; i < numThreads; ++i) {
if (pthread_join(threads[i], nullptr) != 0) {
std::cerr << "Error joining thread " << i + 1 << std::endl;
return 1;
}
std::cout << "Thread " << i + 1 << " has joined." << std::endl;
}
std::cout << "All threads have completed." << std::endl;
return 0;
}
代码解析
-
pthread_create
:- 创建线程时使用
pthread_create
,第一个参数是线程ID的指针,第二个参数是线程的属性(可以传入nullptr
使用默认属性),第三个参数是线程函数的地址,第四个参数是传递给线程函数的参数。 - 每个线程会执行
threadFunc
函数,并接收不同的threadArgs
作为参数。
- 创建线程时使用
-
pthread_join
:- 主线程使用
pthread_join
来等待子线程完成执行。pthread_join
的第一个参数是线程ID,第二个参数用于获取线程的返回值(我们这里传入nullptr
表示不关心返回值)。 pthread_join
可以保证主线程等待所有子线程执行完成后再继续执行。
- 主线程使用
-
threadFunc
:- 这是子线程执行的函数。它的参数是
void*
类型,所以我们需要将其转换为适当的类型(在此例中是int*
)。 - 模拟线程任务时使用
sleep(2)
让线程休眠2秒。
- 这是子线程执行的函数。它的参数是
-
线程参数:
- 为了避免多个线程共享同一个参数导致的问题,我们为每个线程分配一个单独的参数
threadArgs[i]
。
- 为了避免多个线程共享同一个参数导致的问题,我们为每个线程分配一个单独的参数
输出示例
Thread 1 is running.
Thread 2 is running.
Thread 3 is running.
Thread 1 has finished.
Thread 1 has joined.
Thread 2 has finished.
Thread 2 has joined.
Thread 3 has finished.
Thread 3 has joined.
All threads have completed.
线程同步与控制
通过使用 pthread_join
,我们可以确保主线程在所有子线程执行完成之后才继续执行,这样可以避免主线程提前退出而导致子线程未完成的问题。这也是一种常见的线程同步机制。
注意事项
- 数据竞争: 如果多个线程同时访问共享资源而不使用同步机制(如互斥锁
pthread_mutex_t
),可能会导致数据竞争。 - 线程返回值: 如果需要获取线程的返回值,可以在
pthread_join
的第二个参数中提供指针接收线程函数的返回值。 - 线程的可重入性: 如果线程之间共享数据,应确保线程安全,避免数据竞争或不一致的状态。
通过以上代码示例,你可以理解如何使用 pthread_create
和 pthread_join
来实现多线程的同步与控制。