首页 文章

杀死等待条件变量的pthread

提问于
浏览
6

我有一个pthread使用pthread_cond_wait等待条件变量 . 它正在等待来自另一个线程填充的队列结构的数据 . 我想杀死这个帖子,最好没有pthread_kill . 在Linux和WinPthreads上做pthread_cancel(); pthread_join()足以杀死它 . 但是,在OS X上,它挂起在pthread_join调用上 . 有什么建议?

3 回答

  • 0

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

    现在,要关闭这些线程,只需将多个这些"quit"对象发布到队列的 HEAD ,该队列对应于为队列提供服务的线程数,并加入线程 .

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

  • 6

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

    要检查的第一件事是确实在目标线程上启用了取消---在目标线程上显式调用 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,&oldstate) 以确保 . 如果这不是必须求助于诸如设置"please stop now"标志和发信号通知条件变量之类的替代方案 .

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

    顺便说一句 pthread_kill 确实 not 杀了一个线程---它向它发送一个信号 .

  • 7

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

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

    POSIX.1c-2004(v6)规定:

    任何新创建的线程的可取消状态和类型,包括首次调用main()的线程,应分别为PTHREAD_CANCEL_ENABLE和PTHREAD_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之前,我仍然发现自己只是为每个线程使用一个全局变量来指示何时应该退出,同时手动踢互斥或条件变量唤醒线程 . 我想我应该更新我的方法(或者如果我能看到明显的优势,我会这样做) . :-)

相关问题