C++11——多執行緒程式設計6
在這個文章中 我們將討論多執行緒中事件處理的必要性
有時候 執行緒需要等待某件事情發生 比如條件為真或者是任務通過另外一個執行緒被完成了
比如
假設我們正在構建一個基於網路的應用程式。此應用程式執行以下任務,
- 與伺服器執行握手
- 從 XML 檔案載入資料。
- 對從 XML 載入的資料進行處理。
正如我們所見,Task 1 不依賴於任何其他 Task,而 Task 3 依賴於 Task 2。因此,這意味著 Task 1 和 Task 2 可以由不同的執行緒並行執行,以提高應用程式的效能。
所以,讓我們把它分解成一個多執行緒應用程式,
現在,它包括兩個執行緒,
執行緒 1 的職責是,
- 與伺服器執行一些握手。
- 等待執行緒 2 從 XML 載入資料
- 對從 XML 載入的資料進行處理。
執行緒 2 的職責是,
- 從 XML 載入資料
- 通知另一個執行緒,即等待訊息。
在上面,執行緒 1 執行一些操作,然後等待事件/條件發生。這裡的事件或條件是,
資料載入成功。
一旦執行緒 1 接收到該事件,它就會對資料執行一些處理。
執行緒 2,當執行緒 1 忙於做握手機制時並行載入資料。
當執行緒 2 成功地從 XML 載入資料時,它然後通過向該事件發出訊號通知執行緒 1。
現在,當事件或條件發出訊號時,執行緒 1 將繼續處理資料。
使它成為多執行緒有什麼好處?
當執行緒 1 忙於某種握手機制時,執行緒 2 將從 XML 並行載入資料。
實現方式:
實現方式
第一種
建立一個預設為false的boolean型全域性變數,線上程2中將其設為true,執行緒1將會迴圈檢測其值,一旦該值被設為true,執行緒1將會繼續處理資料,
由於它是一個由兩個執行緒共享的全域性變數,需要使用mutex鎖進行同步
#include<iostream> #include<thread> #include<mutex> class Application { std::mutex m_mutex; bool m_bDataLoaded; public: Application() { m_bDataLoaded= false; } void loadData() { // Make This Thread sleep for 1 Second std::this_thread::sleep_for(std::chrono::milliseconds(1000)); std::cout<<"Loading Data from XML"<<std::endl; // Lock The Data structure std::lock_guard<std::mutex> guard(m_mutex); // Set the flag to true, means data is loaded m_bDataLoaded = true; } void mainTask() { std::cout<<"Do Some Handshaking"<<std::endl; // Acquire the Lock m_mutex.lock(); // Check if flag is set to true or not while(m_bDataLoaded != true) { // Release the lock m_mutex.unlock(); //sleep for 100 milli seconds std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Acquire the lock m_mutex.lock(); } // Release the lock m_mutex.unlock(); //Doc processing on loaded Data std::cout<<"Do Processing On loaded Data"<<std::endl; } }; int main() { Application app; std::thread thread_1(&Application::mainTask, &app); std::thread thread_2(&Application::loadData, &app); thread_2.join(); thread_1.join(); return 0; }
該方法存在以下缺陷:
為了檢測變數,執行緒將會持續獲取-釋放鎖,這樣會消耗CPU週期並且使執行緒1變慢,因為它需要獲取相同的鎖來更新bool變數。
因此,顯然我們需要一個更好的實現機制,如某種方式,執行緒1可以通過等待event訊號來阻塞,另一個執行緒可以通知該event並使執行緒1繼續。這將會有相同的CPU週期,並有更好的效能。
第二種
我們可以使用條件變數來實現,條件變數是一種用於在2個執行緒之間進行信令的事件,一個執行緒可以等待它得到訊號,其他的執行緒可以給它發訊號。
下一節會詳細說明這個條件變數,並使用條件變數來解決問題。