C++对象是怎么死的?POSIX线程篇

来源:互联网 发布:第一次sql注入步骤 编辑:程序博客网 时间:2024/06/10 05:23

上一个帖子 聊完了Win32环境下和线程有关的C++对象死亡问题,今天得说一说POSIX的线程库pthread了。如果你对pthread不太了解,可以先看看维基百科 的介绍。

  ★三种死法 
  废话少说,照例先介绍三种死法。
  1、自然死亡
  上一个帖子 已经介绍了Win32线程的自然死亡,pthread的自然死亡和它差不多,也是线程对应的线程函数通过return返回。
  2、自杀
  对于“自杀”,POSIX使用pthread_exit 函数来实现。就一种方式,相比Win32的自杀简单多了,此处省去不少口水。
  3、它杀
  虽然pthread的自杀简单,但是它杀就比较复杂了。所以,我把口水转移到这里,重点说一下它杀的方式。
  在pthread库中主要使用pthread_cancel 杀线程。用pthread_cancel 取消线程还分两种情况:异步取消 (PTHREAD_CANCEL_ASYNCHRONOUS)和延迟取消 (PTHREAD_CANCEL_DEFERRED)。 异步取消是相当粗暴的,不管三七二十一,直接把线程干掉;而延迟取消则比较温柔,被取消的线程会继续运行直到遇见某个“取消点”才终止。由于本帖不是 pthread的入门扫盲帖,关于什么是“取消点”以及线程取消的其它细节,请参考pthread API手册。
  有同学可能会问了,pthread_kill 难道不是用来“它杀”的?其实pthread_kill 只不过是给指定的线程发送信号(signal)而已。哎,当初也不知道是哪个家伙起了pthread_kill 这个函数名,误导了不少同学。另外,使用pthread_kill 有一点要小心,如果对应的线程没有处理 收到的信号,则该信号可能会影响线程所在的进程 ,可能会导致进程终止(相当于进程自杀)。

  ★类对象的析构 
  上一个帖子 已经分析过,和线程有关的C++对象,也就是两种局部对象。请看这两种对象在不同死法上,是否会正常析构。
-------------------------
         局部非静态对象  局部静态对象
  自然死亡     能        能
   自杀     不一定能      能
  它杀(延迟)  不一定能      能
  它杀(异步)   不能       能
-------------------------
  对于上述对照表中的“不一定能”,在Linux平台(具体是RHEL3,GCC 3.2.3)下能够析构,但是在Cygwin(具体是Windows2003,GCC 3.4.4)中不能,所以只好认为是“不一定能析构”。
  由于pthread在不同的操作系统上的实现可能有差异,说不定在某些环境下,自杀和它杀的表现会和上述不一致。假如你发现自己碰到的实际情况和上述不符合,欢迎你通过评论或邮件告诉我,我会补充到本文中 :-) 
  从上表来看,异步它杀是最不安全的,自然死亡还是最安全的。至于自杀和延迟它杀,则要看具体的环境了。

  ★关于主线程之死 
  关于啥是主线程,上一个帖子 已经介绍过了,不再多啰嗦。在POSIX系统里,主线程的自然死亡也会引发exit 被调用,从而导致其它线程被野蛮地干掉(这个情形和Windows系统中类似)。如果希望主线程退出不导致进程自杀,可以使用pthread_exit 来结束主线程,并让其它线程继续运行。不过由于线程自杀在某些环境下也不安全 ,我建议还是让主线程最后退出比较稳妥。

  POSIX系统中,线程相关的对象析构问题,就聊到这里。


版权声明 
本博客所有的原创文章,作者皆保留版权。转载必须包含本声明,保持本文完整,并以超链接形式注明作者编程随想 和本文原始地址:

http://program-think.blogspot.com/2009/03/cxx-object-destroy-with-thread-posix.html

原创粉丝点击