Stack overflow地址:c++ - Cancelling a thread using pthread_cancel : good practice or bad - Stack Overflow
翻譯:
我有一個C++程序在Linux(CentOS 5.3),它產(chǎn)生多個線程,線程在無限循環(huán)執(zhí)行一個任務(wù)并睡眠一定的時間。一旦一個新的配置提醒到來,我就需要取消正在運行的線程然后開啟一些新的線程去更新它們,為此我使用了pthread_cancel。我觀察到,線程不會停止即使收到了取消指示命令,甚至一些睡眠的線程在睡眠之后又出現(xiàn)了。
這并不是希望的行為,請評論一下在上面的場景中 pthread_cancel的用法。
Answers1:
通常情況下線程取消并不是一個好主意。如果有可能的話,共享一個標識,它用于線程退出它們的循環(huán)。那樣,你需要讓線程執(zhí)行一些資源回收操作在真正的退出之前。
在這個問題上,線程實際上沒有取消,POSIX指出了一組取消情況(man 7 pthreads)。只有在這些情況下線程才可以取消。如果你得無限循環(huán)沒有包含一個取消情況,那么你可以添加一個通過調(diào)用?pthread_testcancel。如果?pthread_cancel 被調(diào)用了,它將會在這里執(zhí)行。
Answers2:
如果你在寫異常安全的C++代碼(查閱https://www.boost.org/community/exception_safety.html),那么你得代碼就有線程取消的功能。https://udrepper.livejournal.com/21541.html因此你得析構(gòu)函數(shù)可以做正確的資源釋放。
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 );
}