我有一个C ++插件,我是为专有软件编写的,它对一个名为OpenLibrary的函数进行异步调用。要知道库加载何时完成,我必须注册一个特定的事件。然后,当触发该事件时,将调用OnEvent例程。由于专有原因,此逻辑有些消毒,但异步调用和onEvent触发器正常工作。不幸的是,由于OpenLibrary调用是异步的,因此循环不会被阻止并继续而不等待EVENT_LIBRARY_LOADED事件。我需要连续处理文件。
...
void MyApp::main()
{
for(int i=0; i<total; ++i) {
pData->RegisterEvent( EVENT_LIBRARY_LOADED, this );
pData->OpenLibrary("c:/path/file.dat"); // asynchronous call
}
}
...
void MyApp::OnEvent( ID eventType )
{
if (eventType == EVENT_LIBRARY_LOADED) {
qDebug() << "Library load has completed";
}
}
...
该插件需要VS2008,并且还利用了Qt库。
我想创建一个名为waitForEvent的函数,其中后续代码被阻塞直到事件发生,然后waitForEvent可以将控制权返回给调用例程循环。这样,我可以保持在我的主例程循环中,只需等待事件再继续。任何建议表示赞赏。
更新:我已经尝试了Tas下面的两个优秀建议,但在任何一种情况下,我得到相同的结果。 WaitForSingleObject或condition_variable.wait BOTH阻止EVENT_LIBRARY_LOADED事件触发OnEvent函数被调用,这会冻结循环。
任何更多建议表示赞赏。
答案 0 :(得分:2)
boost::conditional_variable
您已经明确表示C ++ 11不是一个选项(否则您可以使用std::conditional_variable
)。 boost::conditional_variable
将完成您需要做的事情,并且使用起来非常简单。您只需致电wait
和notify_one
:
void MyApp::main()
{
for(int i=0; i<total; ++i) {
pData->RegisterEvent( EVENT_LIBRARY_LOADED, this );
pData->OpenLibrary("c:/path/file.dat"); // asynchronous call
conditional_variable.wait(); // wait until we've been signaled
}
}
void MyApp::OnEvent( ID eventType )
{
if (eventType == EVENT_LIBRARY_LOADED) {
qDebug() << "Library load has completed";
// signal completion:
conditional_variable.notify_one();
}
}
这些工作与上述非常相似,但使用起来有点复杂(以及特定于操作系统)。
HANDLE hEvent = ::CreateEvent(NULL, TRUE, FALSE, NULL);
void MyApp::main()
{
for(int i=0; i<total; ++i) {
// Prepare signal (otherwise if the signal has been Set already, Wait will return instantly)
::ResetEvent(hEvent);
pData->RegisterEvent( EVENT_LIBRARY_LOADED, this );
pData->OpenLibrary("c:/path/file.dat"); // asynchronous call
// wait for event to signal:
::WaitForSingleObject(hEvent, INFINITE);
}
}
void MyApp::OnEvent( ID eventType )
{
if (eventType == EVENT_LIBRARY_LOADED) {
qDebug() << "Library load has completed";
// Signal event:
::SetEvent(hEvent);
}
}