Stack overflow地址:c++ - Cancelling a thread using pthread_cancel : good practice or bad - Stack Overflow
翻译:
我有一个C++程序在Linux(CentOS 5.3),它产生多个线程,线程在无限循环执行一个任务并睡眠一定的时间。一旦一个新的配置提醒到来,我就需要取消正在运行的线程然后开启一些新的线程去更新它们,为此我使用了pthread_cancel。我观察到,线程不会停止即使收到了取消指示命令,甚至一些睡眠的线程在睡眠之后又出现了。
这并不是希望的行为,请评论一下在上面的场景中 pthread_cancel的用法。
Answers1:
通常情况下线程取消并不是一个好主意。如果有可能的话,共享一个标识,它用于线程退出它们的循环。那样,你需要让线程执行一些资源回收操作在真正的退出之前。
在这个问题上,线程实际上没有取消,POSIX指出了一组取消情况(man 7 pthreads)。只有在这些情况下线程才可以取消。如果你得无限循环没有包含一个取消情况,那么你可以添加一个通过调用 pthread_testcancel。如果 pthread_cancel 被调用了,它将会在这里执行。
Answers2:
如果你在写异常安全的C++代码(查阅https://www.boost.org/community/exception_safety.html),那么你得代码就有线程取消的功能。https://udrepper.livejournal.com/21541.html因此你得析构函数可以做正确的资源释放。
Answers3:
我使用 boost::asio。
就像下面这样:
struct Wait {
Wait() : timer_(io_service_), run_(true) {}
boost::asio::io_service io_service_;
mutable boost::asio::deadline_timer timer_;
bool run_;
};
void Wait::doWwork() {
while (run) {
boost::system::error_code ec;
timer_.wait(ec);
io_service_.run();
if (ec) {
if (ec == boost::asio::error::operation_aborted) {
// cleanup
} else {
// Something else, possibly nasty, happened
}
}
}
}
void Wait::halt() {
run_ = false;
timer_.cancel();
}
一旦你掌握了它,asio是一个完美的工具。
Answers4:
你可以使用想下面这样的代码:
#include
#include
#include
...
void *Control(void* pparam)
{
try
{
// do your work here, maybe long loop
}
catch (abi::__forced_unwind&)
{ // handle pthread_cancel stack unwinding exception
throw;
}
catch (exception &ex)
{
throw ex;
}
}
int main()
{
pthread_t tid;
int rtn;
rtn = pthread_create( &tid, NULL, Control, NULL );
usleep(500);
// some other work here
rtn = pthtead_cancel( tid );
}
网友评论