c++ - 为现有异步代码创建 C++ 阻塞函数

标签 c++ asynchronous

我有一个为专有软件编写的 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 两者都会阻止 EVENT_LIBRARY_LOADED 事件触发调用 OnEvent 函数,从而卡住循环。

任何更多建议表示赞赏。

最佳答案

如果可以选择 boost 库,请使用 boost::condition_variable

您已经明确表示 C++11 不是一个选项(否则您可以使用 std::condition_variable)。 boost::condition_variable 将完成您需要做的事情,而且使用起来非常简单。您只需要调用 waitnotify_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
        condition_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:
        condition_variable.notify_one();
    }
}

否则你可以使用 Windows Event objects

这些工作与上面的非常相似,但使用起来稍微复杂一些(而且还特定于操作系统)。

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

关于c++ - 为现有异步代码创建 C++ 阻塞函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30360822/

相关文章:

c++ - 如何解决由继承和嵌套类引起的这种冗余?

c++ - 为什么在这种情况下 cout 不会溢出?

c++ - 是否 sizeof(T) == sizeof(const T) 和 alignof(T) == alignof(const T)

c++ - 如何使用 constexpr 逻辑?

javascript - Node 异步未运行异步

javascript - 从循环nodejs中的函数获取值

c++ - boost::phoenix 相当于什么?

c# - 同步比。 .NET 中的异步套接字性能

ios - Alamofire 在范围之外返回值 - 该代码如何工作?

http - 使用带有 core.async channel 的 http-kit 长轮询