zoukankan      html  css  js  c++  java
  • 信号处理方法的问题

    这周有位新同事请我帮忙看一个关于信号处理的问题,程序希望在收到一个信号后退出,而他在信号处理方法里却做了很多事,包含释放一些全局内存等。


    这样问题就产生了,程序不定时的就挂死了,用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方法来同步处理信号,在这里能够处理一些复杂的操作,不用操心“重入”问题。
  • 相关阅读:
    Unity核心对象模型
    自适应XAML布局经验总结 (四)区域布局设计模式
    自适应XAML布局经验总结 (三) 局部布局设计模式2
    自适应XAML布局经验总结 (二) 局部布局设计模式1
    自适应XAML布局经验总结 (一)原则和页面结构设计
    WPF核心对象模型-类图和解析
    谈谈XAML前端开发
    arpg网页游戏特效播放(一)
    arpg网页游戏之地图(四)
    arpg网页游戏之地图(三)
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4030720.html
Copyright © 2011-2022 走看看