C++ C++;通知等待模式的多线程算法设计

C++ C++;通知等待模式的多线程算法设计,c++,multithreading,C++,Multithreading,我正在寻找以下算法在Windows上的多线程实现的建议和代码示例: 线程1:获取输入1,执行工作,通知线程2,继续工作 线程2:获取input2,执行工作,等待来自线程2的通知,执行一些处理,通知Thread3,继续工作 线程3:获取input3,执行工作,等待来自线程3的通知,执行一些处理,通知Thread4,继续工作。 等等 因为我是C++新手,我不确定在线程间发送/接收通知的机制是什么。 我考虑了几种方法:mutex,信号灯,关键部分,但这些方法似乎主要用于锁定,而不是等待通知。除了您

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

  • 线程1:获取
    输入1
    ,执行工作,通知
    线程2
    ,继续工作
  • 线程2:获取
    input2
    ,执行工作,等待来自线程2的通知,执行一些处理,通知
    Thread3
    ,继续工作
  • 线程3:获取
    input3
    ,执行工作,等待来自线程3的通知,执行一些处理,通知
    Thread4
    ,继续工作。 等等

因为我是C++新手,我不确定在线程间发送/接收通知的机制是什么。


我考虑了几种方法:
mutex
信号灯
关键部分
,但这些方法似乎主要用于锁定,而不是等待通知。

除了您已经列出的常用帮助外,您还应该看看

condition_变量类是一个可以 用于阻止一个线程,或同时阻止多个线程, 直至: -从另一个线程接收到通知 [……]

当使用条件变量时,线程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;
}
std::mutex-mtx;
std::条件变量cv;
静态布尔就绪=错误;
静态空集()
{
{
标准:唯一锁定lck(mtx);
当(!准备就绪)
cv.等待(lck);
}

std::cout假设每个线程的任务函数如下所示:

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
}
这会一直阻塞,直到线程被下一个函数发送的消息唤醒

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;
    }
}
通过魔法

如果您关心发送的消息的类型,您可以发送简单的信息,如
Msg
参数中的数字,然后从
winmsg.message
中提取。请保持数字较小,因为Windows将
消息的上半部分用于自己的恶意目的

如果您需要更复杂的消息传递,请参阅

在OP的例子中,线程1使用线程2的句柄调用postmg来唤醒线程2。线程2使用线程3的句柄调用postmg,依此类推


你甚至可以使用“S”方法来保留大部分的标准库,但我从来没有测试过。让我知道它是否有效。

向我们展示你所尝试的,到目前为止。如果你在Windows上,考虑使用Windows事件会非常慢。只需使用一个简单的布尔函数,用互斥体来保护,这就是所有需要的。不过,这并没有那么慢,可能是他想要的太多了。互斥在这里也太多了。使用原子bool代替。原子也有它的成本,但要轻得多。