我使用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
}
}
答案 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()