已经处于条件变量等待调用的中断提升线程

时间:2015-04-12 23:21:42

标签: c++ multithreading opencv boost

我使用boost interprocess library创建服务器和客户端程序,以便在共享内存中传递opencv mat objects。每个服务器和客户端进程都有两个boost线程,它们是boost :: thread_group的成员。一个处理命令行IO,另一个管理数据处理。使用boost :: interprocess condition_variables同步共享内存访问。

由于这个程序涉及共享内存,我需要在退出前进行一些手动清理。我的问题是,如果服务器提前终止,那么客户端上的处理线程会在wait()调用时阻塞,因为服务器负责发送通知。我需要以某种方式中断卡在wait()的线程以启动共享内存破坏。我理解在线程上调用interrupt()(在我的情况下,thread_group.interrupt_all())将导致在到达中断点时抛出boost::thread_interrupted异常(例如wait()),如果不处理,将允许共享内存销毁继续进行。但是,当我在wait()中尝试中断线程时,似乎没有任何事情发生。例如,这不会向命令行打印任何内容:

try {
    shared_mat_header->new_data_condition.wait(lock);
} catch (...) {
    std::cout << "Thread interrupt occurred\n";
}

我完全不确定,但似乎需要在线程进入interrupt()之前调用wait()调用才能抛出异常。这是真的?如果没有,那么中断被condition_variable.wait()调用阻止的提升线程的正确方法是什么?

感谢您的任何见解。

修改 我接受了Chris Desjardins&#39;答案,它没有直接回答问题,但具有预期的效果。在这里,我翻译了他的代码段,以便与boost::interprocess条件变量一起使用,这些变量的语法与boost::thread条件变量略有不同:

while (_running) {

    boost::system_time timeout = boost::get_system_time() + boost::posix_time::milliseconds(1);

    if (shared_mat_header->new_data_condition.timed_wait(lock, timeout)) 
    {
        //process data
    }
}

2 个答案:

答案 0 :(得分:2)

我更喜欢等待超时,然后检查等待通话的返回代码,看它是否超时。实际上我有一个我想使用的线程模式来解决这种情况(以及c ++中线程的其他常见问题)。

http://blog.chrisd.info/how-to-run-threads/

你的要点是不要在一个线程中无限制地阻塞,所以你的线程看起来像这样:

while (_running == true)
{
    if (shared_mat_header->new_data_condition.wait_for(lock, boost::chrono::milliseconds(1)) == boost::cv_status::no_timeout)
    {
        // process data
    }
}

然后在你的析构函数中设置_running = false;并加入主题。

答案 1 :(得分:0)

尝试使用&#34;通知功能&#34;。保持指向条件变量的指针并调用它而不是中断线程。中断比通知呼叫要昂贵得多。

所以不要做

thread_group.interrupt_all()

改为呼叫

new_data_condition_pointer->notify_one()