在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
來實現多執行緒的同步與控制。