杀死等待条件变量的pthread

时间:2010-08-20 04:43:08

标签: c++ pthreads

我有一个使用pthread_cond_wait()等待条件变量的pthread。它正在等待来自另一个线程填充的队列结构的数据。我想杀死这个帖子,最好没有pthread_kill()

在Linux和WinPthreads上做

pthread_cancel();
pthread_join()

足以杀死它。

但是,在OS X上它挂起pthread_join()电话。有什么建议吗?

3 个答案:

答案 0 :(得分:7)

pthread_cancel应该唤醒pthread_cond_wait中被阻止的线程---这是必需的取消点之一。如果它不起作用则会出现问题。

要检查的第一件事是确实在目标线程上启用了取消---在目标线程上显式调用pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate)以确保。如果这不起作用,那么您的平台上的取消就会被取消,您将不得不采取其他方法,例如设置“请立即停止”标志并发出条件变量信号。

不要使用异步取消,除非你真的知道你在做什么 - 它可以在任何操作的中间触发取消(例如在中间设置函数调用堆栈框架或运行析构函数),因此可以使代码处于完全不一致的状态。编写异步取消安全代码 hard

顺便说一下pthread_kill 杀死一个帖子---它会向它发送一个信号。

答案 1 :(得分:7)

您是否可以访问队列,并控制排队项目的对象架构?如果是这样,请定义一个队列对象类型,在排队时指示正在处理项目的线程正常退出。

现在,要关闭这些线程,只需将一些“退出”对象发布到队列的 HEAD ,该对象与服务队列的线程数相对应,然后加入线程。

这似乎比pthread_cancel / kill的“核选项”更清晰。

答案 2 :(得分:0)

我要尝试的第一件事就是在取消和连接之间启动条件变量,让目标线程在从条件等待返回后明确检查取消。

那是因为可能是线程在条件等待(或根本没有)的情况下没有响应取消。

POSIX.1c-2004(v6)声明:

  

任何新创建的线程的可取消状态和类型,包括首次调用main()的线程,应分别为PTHREAD_CANCEL_ENABLEPTHREAD_CANCEL_DEFERRED

这意味着您必须使用pthread_testcancel()明确检查取消。

另一个选项是在第一次开始运行时将线程取消类型设置为PTHREAD_CANCEL_ASYNCHRONOUS,如:

int junk;
pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, &junk);
std::cout
    << ((junk==PTHREAD_CANCEL_DEFERRED) ? "Was deferred" : "Wasn't")
    << std::endl;

当然,这就是假设问题所在。您应该能够通过检查上面第三行的输出来测试它是否正确。

取消是目标线程的请求,如果愿意,它可以自由忽略,而不是更邪恶的pthread_kill()。我非常相信让线程控制自己的生命,因为我发现它总是导致更少的并发问题。

  

旁白:事实上,在早期版本的pthreads中被收购,甚至在集成到DCE之前,我仍然发现自己只是为每个使用一个全局变量线程指示何时应该退出,以及手动踢互斥锁或条件变量以唤醒线程。我想我应该更新我的方法(或者如果我能看到明显的优势,我会这样做)。 : - )