Linux信号处理方法的问题

来源:本站
导读:目前正在解读《Linux信号处理方法的问题》的相关信息,《Linux信号处理方法的问题》是由用户自行发布的知识型内容!下面请观看由(电工技术网 - www.9ddd.net)用户发布《Linux信号处理方法的问题》的详细说明。
简介:本文主要介绍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

#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方法来同步处理信号,在这里可以处理一些复杂的操作,不用担心“重入”问题。

提醒:《Linux信号处理方法的问题》最后刷新时间 2024-03-14 01:01:48,本站为公益型个人网站,仅供个人学习和记录信息,不进行任何商业性质的盈利。如果内容、图片资源失效或内容涉及侵权,请反馈至,我们会及时处理。本站只保证内容的可读性,无法保证真实性,《Linux信号处理方法的问题》该内容的真实性请自行鉴别。