C++ Win事件由增强信号取代(threadsafe)

C++ Win事件由增强信号取代(threadsafe),c++,boost,C++,Boost,我想用一些可移植的东西更改win32事件,所以我决定使用boost.signals2 现在我有一些类似于: ret = WaitForMultipleObjets { switch(ret) { case Timeout: something; break; case Event1: something; break; case Event2: something; break; } } 我认为最好用这样的东西来代替这个:

我想用一些可移植的东西更改win32事件,所以我决定使用boost.signals2

现在我有一些类似于:

ret = WaitForMultipleObjets
{
    switch(ret)
    {
        case Timeout: something; break;
        case Event1: something; break;
        case Event2: something; break;
    }
}
我认为最好用这样的东西来代替这个:

for(;;)
{
    Execute code from timeout, if event occurs interrupt and execute
    code which is responsible for event handling
}
但我不知道该如何实现这一点。也许我可以加入lambda插槽的信号,并造成中断超时代码(通常的例行程序)

最好的问候

Win32事件的“直接”翻译应该是
std::condition_variable
boost::condition_variable

因为
signals2
并不意味着任何类型的同步,如果要获得相同的语义,需要替换它

也就是说,对于事件驱动的代码,我通常使用Boost Asio,如果它更像是在线程之间传递消息,则使用IPC的(消息)队列

以下是Boost Asio的想法:

#include <iostream>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <iostream>

using namespace boost;
namespace as = boost::asio;

// basically used as a callback queue for the simple reason we don't do
// asynchronous IO (yet)
as::io_service shared_queue; 

void worker(int id) {
    while (!shared_queue.stopped()) {
        this_thread::sleep_for(chrono::milliseconds(rand() % 1000));

        shared_queue.post([id] {
                std::cout << "event from thread #" << id << " handled on " << this_thread::get_id() << "\n";
            });
    }
}

int main() {
    thread_group threads;

    threads.create_thread(bind(worker, 1)); // arbitrary number of sources for events
    threads.create_thread(bind(worker, 2));
    threads.create_thread(bind(worker, 3));

    {
        as::io_service::work keep_running(shared_queue);
        threads.create_thread([] { shared_queue.run(); });

        this_thread::sleep_for(chrono::seconds(4));
    } // after 4 seconds, `keep_running` is destructed, making `run()` exit when idle

    shared_queue.stop();

    threads.join_all();
}
我尝试在boost上移植,但如果在多个位置等待同一事件,可能会导致作用域锁上的死锁(这在boost中等待cond var时是必要的)

所以这次我试着这样做:

for(;;)
{
    auto c = signal.connect([]()
    {
        ThreadHandle->interrupt();
        //code for handling event1
    });

    try
    {
        //code for timeout
    }
    catch (boost::thread_interrupted&)
    {
        //thread interrupted by signal listener
        boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
    }
}

当信号被“捕获”时,我中断主流(超时),并做一些在事件发生时应该做的事情。

这是我书中的代码气味;您正在使用线程来空闲(这不会扩展),并且还在流控制中使用异常是的,这是答案,但我也希望对我的想法发表意见。你能告诉我这本书的标题吗?我在操作中读C++并发:实用的多线程,但是我不使用这本书来编写这个代码。但让我们回到主要问题上来,您认为这是一个很好的解决方案吗我在回答中添加了一种方法。其他的死锁(很大程度上)依赖于实际代码库中的使用方式。如果你不能弄清楚,我会询问具体的死锁。Boost的自由功能变体为
lock
,可使用多个锁。您可以使用它来等待多个锁而不发生死锁。我不确定reursive mutex是否可以在条件变量boost::mutex::scoped_lock lock(event->mutex)中使用;结果=event->CVariable.timed_wait(锁,boost::posix_time::毫秒(毫秒));这是一个将Boost-Asio方法添加到事件队列中的“正常”互斥的示例。注意:您可以在
共享_队列
上添加任意数量的调用
run()
的线程(只要您采取所有常规预防措施w.r.t.访问共享数据)。请注意,
boost::asio::io\u服务本身是线程安全的
for(;;)
{
    auto c = signal.connect([]()
    {
        ThreadHandle->interrupt();
        //code for handling event1
    });

    try
    {
        //code for timeout
    }
    catch (boost::thread_interrupted&)
    {
        //thread interrupted by signal listener
        boost::this_thread::sleep_for(boost::chrono::milliseconds(1000));
    }
}