关闭一个线程
注意:由于个人能力及知识水平问题,以下内容可能有原则性错误,请批判着阅读!
最近搜东西,又搜到了这个关于pthread_kill的话题,相信有不少人看过这个讨论。NPTL的作者真霸道。看了几遍pthread_kill的手册,然后放心的写代码,然后得到一个core dump,相信谁都会不爽的。
但用pthread_kill(pid, 0)来检测一个线程的运行情况是一件不靠谱的行为,虽然这是非常普遍的行为:Joinable的线程完结了,还没执行pthread_join(),这个状态,pthread_kill(pid, 0)能正常识别么?规范没有说,其实很多实现都没有能够区分这两种状态吧。(1 运行中, 2 运行结束,还没join)还有一种比较不大可能发生的事情——通常,你的代码能提前发现这个问题:pid如果被重用了呢?这种时候,其实你检查的是一个全新的线程。
pthread_kill()是一个非常难用的方法,在确定你的线程能正确的处理信号之前,不能随意的向某个线程发出信号;如果你的程序不能正确处理,你的整个系统都会由于这个方法的调用而终止。出于对其的害怕,我从来没有在自己的代码里使用过它。
如果要关闭一个Server线程,其实可以为线程提供一个shutdown()方法,像所有Java程序员都会的那样;如果要立刻终止一个线程,可以用pthread_cancel(pthread_t),当然这个方法也会有风险(你不知道你要关闭的线程是不是已经终止了,你也不知道你要关闭的线程或许是一个全新的线程)。所以,pthread_cancel(pthread_t)方法需要在同步块内调用,调用前,确认 线程处于有效的状态。而线程也需要在同步块内才能改变自己的状态。
我觉得安全的做法,不论是pthread_cancel,或是pthread_kill,都需要利用同步机制,确认线程先有效,再操作。当然,很多人不这么认为,因为他们的代码从不这样写。
