小公司研发总监,既当司令也当兵!
分类: LINUX
2016-07-14 09:13:54
原文地址:多线程信号屏蔽测试 作者:qq2000zhong
操作系统:Linux test12 2.6.18-308.8.1.el5
多线程的信号处理是个比较头痛的事情,网上查阅了很多资料,有一篇比较详细:
其实理想的情况是:子线程屏蔽了所有信号,主线程注册了所有信号处理;
网上资料多提到用 pthread_sigmask 来屏蔽信号,经过测试,发现一些现象:
1,这个函数不能屏蔽 SIGSTOP, SIGKILL, SIGSEGV, SIGFPE, SIGBUS 等信号,前两个比较好理解,后三个不好理解;后三个信号如果强制屏蔽,即使在
主线程加入了这两者的处理函数,仍然得不到调用,且进程会直接退出,父进程可以得到完整的退出信息(退出信号和是否有coredump);所以如果
确实需要在进程中捕获,子线程是不能直接屏蔽这三个信号的;
注:如果是从用 pthread_kill 产生的 SIGSEGV, SIGFPE,SIGBUS 不属于特殊之列--即可以屏蔽由主线程处理;
2,其他信号,如果直接从外面 kill 或 pthread_kill 都可以直接屏蔽,由主线程处理;//但因为内核不区分信号从哪里来,所以...
3,在子线程中 abort 退出(比如abort()或者assert()之类),主线程能截获这个信号并加以处理;
btw:为了在子线程中产生 SIGBUS 信号,还真不容易,传说中的对齐竟然毫发无损的运行通过了,然后通过mmap,mmap写或者读超出初始文件长度
直接产生了 SIGSEGV,而不是 SIGBUS 信号;后来只能通过在测试程序中mmap一定长度的文件,然后在运行的过程中,由另外的进程去truncate
这个文件,最后才生成了 SIGBUS,且发现:这个 SIGBUS 不是超出文件的长度就会产生的,是要超出一定的距离才产生,我的测试中,mmap文件
初始长度为 8192,另外的进程turncate到1024后,mmap读取到 3840 字节左右(试了好几次)才产生 SIGBUS 挂掉的,至于什么原因就不清楚了。