1. 程式人生 > 其它 >C++11——多執行緒程式設計6

C++11——多執行緒程式設計6

在這個文章中 我們將討論多執行緒中事件處理的必要性

有時候 執行緒需要等待某件事情發生 比如條件為真或者是任務通過另外一個執行緒被完成了

比如

假設我們正在構建一個基於網路的應用程式。此應用程式執行以下任務,

  1. 與伺服器執行握手
  2. 從 XML 檔案載入資料。
  3. 對從 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個執行緒之間進行信令的事件,一個執行緒可以等待它得到訊號,其他的執行緒可以給它發訊號。
下一節會詳細說明這個條件變數,並使用條件變數來解決問題。