在Linux下,C++可以通過多種方式實現多線程同步。以下是一些常用的同步機制:
互斥鎖(Mutexes):
std::mutex
: C++標準庫提供的互斥鎖,用于保護共享資源。std::lock_guard
: RAII風格的互斥鎖管理類,它在構造時鎖定互斥鎖,在析構時自動解鎖。std::unique_lock
: 提供比std::lock_guard
更靈活的鎖定機制,允許延遲鎖定、時間鎖定等。條件變量(Condition Variables):
std::condition_variable
: 與互斥鎖一起使用,允許線程等待某個條件成立。std::condition_variable_any
: 類似于std::condition_variable
,但可以與任何鎖類型一起使用。讀寫鎖(Read-Write Locks):
std::shared_mutex
: C++17引入的讀寫鎖,允許多個讀取者或一個寫入者訪問共享資源。std::shared_lock
: 與std::shared_mutex
配合使用,用于讀取操作。原子操作(Atomic Operations):
std::atomic
: C++11引入的模板類,用于執行原子操作,保證操作的原子性,無需使用互斥鎖。屏障(Barriers):
std::barrier
: C++20引入的同步原語,用于使一組線程互相等待到達某個點。信號量(Semaphores):
sem_wait
, sem_post
, sem_init
等函數來使用。下面是一個簡單的例子,展示了如何使用std::mutex
和std::condition_variable
來實現線程同步:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void print_id(int id) {
std::unique_lock<std::mutex> lck(mtx);
while (!ready) {
cv.wait(lck); // 等待條件變量
}
// 打印線程ID
std::cout << "Thread " << id << std::endl;
}
void go() {
std::lock_guard<std::mutex> lck(mtx);
ready = true; // 改變條件變量
cv.notify_all(); // 喚醒所有等待的線程
}
int main() {
std::thread threads[10];
// 創建多個線程
for (int i = 0; i < 10; ++i) {
threads[i] = std::thread(print_id, i);
}
std::cout << "10 threads ready to race..." << std::endl;
go(); // 改變條件并喚醒線程
for (auto &th : threads) {
th.join(); // 等待所有線程完成
}
return 0;
}
在這個例子中,我們創建了10個線程,它們都在等待一個條件變量cv
被通知。主線程通過調用go()
函數來改變條件變量ready
的狀態,并通過cv.notify_all()
來喚醒所有等待的線程。一旦被喚醒,線程將檢查條件變量ready
,如果為true
,則繼續執行。
請注意,多線程編程需要小心處理同步問題,以避免死鎖、競態條件等問題。務必確保在使用共享資源時正確地鎖定和解鎖互斥鎖,并且在適當的時候使用條件變量來同步線程。