面向通知-等待模式的c++多线程算法设计

C++ multi-threaded algorithm design for notify-wait pattern

本文关键字:多线程 c++ 算法 模式 通知 等待      更新时间:2023-10-16

我正在寻找以下算法在Windows上多线程实现的建议和代码示例:

  • Thread1:取input1,做工作,通知Thread2,继续工作
  • Thread2:取input2,做工作,等待Thread2通知,做一些处理,通知Thread3,继续工作
  • Thread3:取input3,做工作,等待Thread3的通知,做一些处理,通知Thread4,继续工作。等

由于我是c++新手,我不确定在线程之间选择哪种机制发送/接收通知。
我考虑了几种方法:mutexsemaphorecritical section,但这些方法似乎主要用于锁定,而不是用于wait-notify。

除了您已经列出的常用帮助器之外,您还应该看看条件变量。

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;
}

假设每个线程的任务函数看起来像这样:

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的上半部分来达到它自己的邪恶目的。

如果你需要更复杂的消息传递,互斥锁没有正确使用?过去疑问句的继续题涵盖了这个。

所以在OP的情况下,线程1用线程2的句柄调用PostMsg来唤醒线程2。线程2使用线程3的句柄调用PostMsg,以此类推。

您甚至可以使用std::thread的native_handle方法来主要保持在标准库中,但我从未测试过这个。