Linux信号处理方法的问题
|
这周有位新同事请我帮忙看一个关于信号处理的问题,程序希望在收到一个信号后退出,而他在信号处理方法里却做了许多事,包括释放一些全局内存等。 这样问题就产生了,程序不定时的就挂死了,用gdb一看,所有的线程都挂在了pthread_once方法里,而似乎每个线程都在处理信号,其中产生问题的线程堆栈如下: Thread 1 (Thread 0x7f41252f3720 (LWP 31542)): #0 0x000000339860cb1b in pthread_once () from /lib64/libpthread.so.0 #1 0x00000033982fd6f4 in backtrace () from /lib64/libc.so.6 #2 0x000000339826fa4b in __libc_message () from /lib64/libc.so.6 #3 0x0000003398275366 in malloc_printerr () from /lib64/libc.so.6 #4 0x0000003398278de4 in _int_malloc () from /lib64/libc.so.6 #5 0x0000003398279b91 in malloc () from /lib64/libc.so.6 #6 0x00007f41253b40bd in operator new(unsigned long) () from /usr/lib64/libstdc++.so.6 更多精彩内容:http://www.bianceng.cn/OS/Linux/ #7 0x00007f41253b41d9 in operator new[](unsigned long) () from /usr/lib64/libstdc++.so.6 ---Type <return> to continue, or q <return> to quit--- #8 0x000000000045f86a in log4cpp::StringUtil::vform(char const*, __va_list_tag*) () #9 0x000000000044eb69 in log4cpp::Category::_logUnconditionally(int, char const*, __va_list_tag*) () #10 0x000000000044f4af in log4cpp::Category::warn(char const*, ...) () #11 0x00000000004431a1 in singalHandler(int) () #12 <signal handler called> #13 0x000000339860cb19 in pthread_once () from /lib64/libpthread.so.0 #14 0x00000033982fd6f4 in backtrace () from /lib64/libc.so.6 #15 0x000000339826fa4b in __libc_message () from /lib64/libc.so.6 #16 0x0000003398275366 in malloc_printerr () from /lib64/libc.so.6 #17 0x0000003398278de4 in _int_malloc () from /lib64/libc.so 问题在哪里呢?似乎所有开源代码里,都少有人在信号处理方法里写大量代码的,这是为什么呢? 原因在于,信号是可能在任意时刻打断你线程的正在执行代码,信号处理方法插入进去执行时,就可能造成有些函数被反复重入。例如上面这个例子中,thead1正在new一个对象,执行malloc分配内存的过程中,突然被信号打断,而信号处理方法里居然又有malloc过程,而malloc是不能反复重入的!于是导致挂死。 另一个问题的,子进程会继承父进程的很多资源,其中就包括信号,他的程序处理信号后,才pthread_create许多工作线程,而且,没有屏蔽信号,所以,所有的线程都在处理那个信号处理方法,所有线程都挂死了。 解决方法有很多种,通常是在信号处理方法里只做少量工作,通知其他线程自我回收资源。 对于多线程程序来说,只弄一个线程使用阻塞式信号处理方法,专职的处理信号,这样更符合多线程的设计精神。例如,在派生子线程前,用pthread_sigmask来设置信号不会打断子线程的运行,而在主线程里,使用阻塞的sigwait方法来同步处理信号,在这里可以处理一些复杂的操作,不用担心“重入”问题。 (编辑:佛山站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |

