中断已经处于条件变量等待调用中的升压线程
Interupt boost thread that is already in condition variable wait call
我在共享内存中使用 boost interprocess library to create server and client programs for passing 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 的回答,它没有直接回答问题,但起到了预期的效果。在这里,我正在翻译他的代码片段以用于 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
}
}
尝试使用 "notify function"。保留指向条件变量的指针并调用它而不是中断线程。中断比通知调用的成本高得多。
所以不做
thread_group.interrupt_all()
改用这个
new_data_condition_pointer->notify_one()
我更喜欢超时等待,然后检查等待调用的 return 代码以查看它是否超时。事实上,我有一个我喜欢使用的线程模式来解决这种情况(以及 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;并加入主题。
我在共享内存中使用 boost interprocess library to create server and client programs for passing 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 的回答,它没有直接回答问题,但起到了预期的效果。在这里,我正在翻译他的代码片段以用于 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
}
}
尝试使用 "notify function"。保留指向条件变量的指针并调用它而不是中断线程。中断比通知调用的成本高得多。
所以不做
thread_group.interrupt_all()
改用这个
new_data_condition_pointer->notify_one()
我更喜欢超时等待,然后检查等待调用的 return 代码以查看它是否超时。事实上,我有一个我喜欢使用的线程模式来解决这种情况(以及 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;并加入主题。