在 C++ 中等待通知

Wait for a notification in C++

提问人:Luchian Grigore 提问时间:10/13/2011 更新时间:10/13/2011 访问量:1062

问:

与 C++ 没有严格关系,我正在寻找更多的设计模式或有关如何解决这个问题的建议。

说我有

class A
{
public:
   void process();
   void wait();
}

我将首先调用 ,它 (duuh) 进行一些处理,然后调用 。该函数应该等待通知,然后退出。我已经在单独的线程上拥有通知的逻辑,但我不太确定最好的方法是什么。process()wait()wait()

我想到的是:

void A::wait()
{
   while ( _notificationOccured == false )
   {
   }
}

其中可以成为 BOOL 成员的位置将通过通知进行更改。但是,同样,我不确定这是否是最好的方法。有什么建议吗?_notificationOccuredA

C++ 设计模式 与语言无关的 通知 等待

评论


答:

0赞 Nim 10/13/2011 #1

两个选项:

  1. 信号灯
  2. 条件

两者都是特定于操作系统的,boost 支持后者。还有其他方法(例如原子操作,但这些操作的公开方式是特定于编译器的)。恕我直言,我会使用上述方法之一。

评论

0赞 Nim 10/13/2011
@Maxim,没有提到操作系统或任何关于线程如何交互的特定机制。在这一点上,所能提供的只是一个通用机制......
0赞 Nim 10/13/2011
@LuchianGrigore,这是MSDN的一个足够简单的例子 - msdn.microsoft.com/en-us/library/windows/desktop/...
0赞 Maxim Egorushkin 10/13/2011
@Nim,如果不是特定于操作系统,只需使用 .std::async()
0赞 Nim 10/13/2011
@Maxim,这假设是 C++11,这又与问题无关......
2赞 Karoly Horvath 10/13/2011 #2

你所做的被称为忙于等待

有各种技术可以更好地做到这一点,最简单的方法是使用带有 ncondition 通知的普通互斥锁 (win32/pthreads/boost)。

评论

0赞 Luchian Grigore 10/13/2011
在提供的链接中,我还看到一个循环,当变量发生变化时,该循环会退出,这是我想避免的。
0赞 Karoly Horvath 10/13/2011
yolinux.com/TUTORIALS/ 的 Condition Variables 部分...
0赞 Luchian Grigore 10/13/2011
我在 Windows 上运行它,但无法真正获得提升(不是我的选择)。
2赞 Alex F 10/13/2011 #3

变量的池化性能很差,因为池化线程几乎占用了所有的 CPU 时间。你需要使用事件或消息 - 这些东西是特定于平台的。为此,您可以使用一些可移植库,例如 Boost。

评论

0赞 Luchian Grigore 10/13/2011
我知道池化不好,这就是为什么我需要建议。我已经有活动了,但我不确定这会有什么帮助。你能扩展一点,也许发布一些代码吗?
0赞 Björn Pollex 10/13/2011
@Alex:投票不一定是坏事。自旋锁就是这样做的。
0赞 Alex F 10/13/2011
如果不想使用 Boost,请查看 Windows API:CreateEvent、SetEvent、WaitForSingleObject。SetEvent 的工作方式类似于 _notificationOccured = true。WaitForSingleObject 取代了繁忙的等待。
1赞 Björn Pollex 10/13/2011 #4

您当前的方法引入了电源环路,这将扼杀您正在运行的系统的性能。您应该引入较短的睡眠时间(10 毫秒就足够了)以防止这种情况发生。更好的是,使用一个库,比如 Boost(如@Nim建议的那样)。

顺便说一句,像你这样的民意调查并不全是坏事。事实上,这就是所谓的自旋锁的作用。这个想法是,如果预期的等待时间很短,那么短时间的轮询比锁定更有效。

评论

0赞 Luchian Grigore 10/13/2011
请参阅对 Alex 答案的评论。
0赞 codencandy 10/13/2011 #5

我只从 Windows 中知道这一点,所以我不知道这是否很容易转换为其他平台。

在伪代码中:

Timer myTimer(1, MYEVENT); // elapses every second
SetTimer( myTimer );       // register timer with event loop

while( running )
{
  if( GetEvent() == MYEVENT )
  {  

  }
}

在 Windows 中,GetEvent() 称为 WaitForSingleObject(...)