2015-09-08 61 views
1

我正在尋找一個多線程執行以下算法中的Windows中的意見和代碼示例:C++多線程算法設計通知,等待模式

  • 線程1:取input1,做的工作,通知Thread2,繼續工作。
  • 線程2:取input2,做功,等待來自線程2的通知,做一些處理,通知Thread3,繼續工作。
  • 線程3:取input3,做功,等待來自線程3的通知,做一些處理,通知Thread4,繼續工作。 等。

由於我新手,C++,我不知道該選擇什麼樣的機制來發送/線程之間收到通知。
我考慮了幾種方法:mutex,semaphore, critical section,但這些似乎主要鎖定,而不是等待通知。

+0

向我們展示你到目前爲止所嘗試過的。 – ravenspoint

+0

如果您在Windows上,請考慮使用[Windows事件](https://msdn.microsoft。com/en-us/library/windows/desktop/ms682655(v = vs.85).aspx) – Serdalis

+0

使用Windows事件會非常慢!只需使用一個簡單的布爾值,用互斥體保護,這就是所需要的。 – ravenspoint

回答

3

除了你已經列出的常用幫手,你應該看看condition variable

的condition_variable類是原始的同步,可以 可以用來阻塞線程,或者在同一時間的多個線程,直到 : - 一通知從另一個線程接收 [...]

當使用條件變量時,線程2可以等待直到它被「通知」,以便線程2可以繼續,等等。下面是一個簡單的例子:

std::mutex mtx; 
std::condition_variable cv; 
static bool ready = false; 

static void set() 
{ 
    { 
    std::unique_lock<std::mutex> lck(mtx); 
    while (!ready) 
     cv.wait(lck); 
    } 

    std::cout << "message received" << std::endl; 
} 

static void go() 
{ 
    std::unique_lock<std::mutex> lck(mtx); 
    ready = true; 

    // here we set the condition variable for thread1 
    cv.notify_all(); 
} 

int main() 
{ 
    std::thread thread1 = std::thread(set); 

    go(); 
    thread1.join(); 
    return 0; 
} 
0

說每個線程的任務功能看起來是這樣的:

void threadfunc() 
{ 
    MSG winmsg; 
    BOOL rval; 

    while (GetMessage(&winmsg, (HWND__ *) -1, 0, 0) != -1) 
    { 
     DoThreadProcessing(); 
    } 
    // GetMessage failed. Find out why and try to recover or die gracefully 
} 

GetMessage此塊直到線程是由這個未來函數發送一個消息的到來喚醒

bool PostMsg(DWORD & ThreadId) 
{ 
    if (PostThreadMessage(ThreadId, 
          WM_USER, 
          (WPARAM) NULL, 
          0); != 0) 
    { 
     return true; 
    } 
    else 
    { 
     // failed. Find out why and try to recover or die gracefully 
     return false; 
    } 
} 

通過神奇的PostThreadMessage

如果你關心發送什麼類型的消息,你可以發送簡單的信息,如Msg參數中的一個數字,並從winmsg.message中取出。由於Windows使用message的上半部分來實現其自身的惡意目的,因此請將該數字保持較小。

如果您需要更復雜的消息,請致電Mutex not correctly used? Continuation of past questions

所以在OP的情況下,線程1調用PostMsg和線程2的句柄來喚醒線程2.線程2調用PostMsg和線程3的句柄等等。

你甚至可以使用std::threadnative_handle方法主要保留在標準庫中,但我從來沒有測試過。讓我知道它是否有效。