在 C++ 中,線程相關功能主要通過頭文件提供的類和函數來實現,以下是一些常用的線程接口方法和使用技巧:
std::thread類
構造函數:
可以通過傳入可調用對象(如函數指針、函數對象、lambda 表達式等)來創建一個線程實例,啟動一個新線程去執行對應的任務。例如:
#include <iostream>
#include <thread>void hello() {std::cout << "Hello from thread!" << std::endl;
}int main() {std::thread t(hello); // 創建線程t并開始執行hello函數t.join(); // 等待線程t執行完畢return 0;
}
這里std::thread t(hello)就是利用函數指針hello創建線程,新線程會執行hello函數里的代碼。
join方法:
用于阻塞當前線程,直到被調用的線程執行完成。比如在上面的main函數中,t.join()會讓main線程暫停,等待t線程把hello函數執行完后再繼續往下執行。
detach方法:
將線程分離,使得線程在后臺獨立運行,不再與創建它的std::thread對象關聯。此后,無法再通過該std::thread對象對這個線程進行控制(比如不能再調用join了)。示例:
#include <iostream>
#include <thread>void func() {// 線程執行的函數內容std::cout << "Thread is running independently." << std::endl;
}int main() {std::thread t(func);t.detach(); // 分離線程t// 主線程繼續執行其他操作,不用等待t線程結束std::cout << "Main thread continues." << std::endl;return 0;
}
線程傳參
向線程函數傳遞參數時,需要保證參數在傳遞時是有效的,且在被調用函數執行期間持續有效(比如避免傳引用指向臨時對象等情況)。例如:
#include <iostream>
#include <thread>void print_num(int num) {std::cout << "The number is: " << num << std::endl;
}int main() {int num = 10;std::thread t(print_num, num); // 傳遞普通變量num作為參數t.join();return 0;
}
如果要傳遞類對象等更復雜的情況,要注意拷貝、移動語義等相關問題,確保參數傳遞的正確性。
線程 ID 獲取
可以通過std::this_thread::get_id獲取當前線程的線程 ID,或者通過std::thread對象的get_id成員函數獲取對應的線程 ID,用于標識和區分不同線程。示例:
#include <iostream>
#include <thread>void show_thread_id() {std::cout << "Thread ID: " << std::this_thread::get_id() << std::endl;
}int main() {std::thread t(show_thread_id);std::cout << "Main thread ID: " << std::this_thread::get_id() << std::endl;t.join();return 0;
}
線程同步相關(例如互斥量等,用于解決多線程訪問共享資源沖突問題)
std::mutex(互斥量):
通過lock和unlock方法對共享資源進行加鎖和解鎖,確保同一時刻只有一個線程能訪問被保護的共享資源。例如:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {for (int i = 0; i < 1000; ++i) {mtx.lock(); // 加鎖shared_data++;mtx.unlock(); // 解鎖}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Shared data value: " << shared_data << std::endl;return 0;
}
也可以使用std::lock_guard等 RAII(Resource Acquisition Is Initialization)機制的類來更方便、安全地管理互斥量的生命周期,自動完成加鎖和解鎖,如:
#include <iostream>
#include <thread>
#include <mutex>std::mutex mtx;
int shared_data = 0;void increment() {for (int i = 0; i < 1000; ++i) {std::lock_guard<std::mutex> guard(mtx); // 構造時加鎖,析構時自動解鎖shared_data++;}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();std::cout << "Shared data value: " << shared_data << std::endl;return 0;
}
std::condition_variable(條件變量):
常和互斥量配合使用,用于線程間的同步,實現一個線程等待某個條件滿足后再繼續執行的功能。比如一個線程等待另一個線程修改共享資源達到某個條件后再進行后續操作,典型用法如下:
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void wait_for_signal() {std::unique_lock<std::mutex> lck(mtx);cv.wait(lck, []{ return ready; }); // 等待條件滿足(ready為true)std::cout << "Received signal and continue." << std::endl;
}void send_signal() {{std::lock_guard<std::mutex> lck(mtx);ready = true;}cv.notify_one(); // 通知等待在該條件變量上的一個線程
}int main() {std::thread t1(wait_for_signal);std::thread t2(send_signal);t1.join();t2.join();return 0;
}
這些就是 C++ 中線程相關的一些主要接口方法及其基本使用方式,在實際多線程編程中,往往需要綜合運用它們來實現高效、正確的并發程序邏輯。