zoukankan      html  css  js  c++  java
  • linux c开发: 在程序退出时进行处理

    有时候,希望程序退出时能进行一些处理,比如保存状态,释放一些资源。c语言开发的linux程序,有可能正常退出(exit),有可能异常crash,而异常crash可能是响应了某信号的默认处理。这里总结一下这些情况,如何获取一个统一的退出处理的点,说白了就是写一个回调函数,让他在程序正常或异常退出时调用。

    • 先看正常退出,即调用exit或者main函数return亦或最后一个线程正常退出时,如何捕获退出事件。 
      使用atexit函数。头文件:#include<stdlib.h>, 函数原型:void atexit(void (*func)(void)); 
      atexit可以调用多次,注册多个回调函数,在进程退出时调用,同一个函数可以被注册多次。使用示例:
    void server_on_exit(void)
    {
        //do something when process exits
    }
    int main(int argc, char *argv[])
    {
        atexit(server_on_exit);
    
        return 0;
    }
    

      

    • 再看异常退出,如abort,响应某些signal的默认处理是异常退出,还有直接kill进程。 
      处理方法是使用signal函数,注册自己的回调函数,而避免系统默认的回调,系统默认的回调可能就是直接crash掉程序。使用例子:
    #include <signal.h>
    void signal_crash_handler(int sig)
    {
        server_backtrace(sig);
        exit(-1);
    }
    
    void signal_exit_handler(int sig)
    {
        exit(0);
    }
    
    int main(int argc, char *argv[])
    {
        atexit(server_on_exit);
        signal(SIGTERM, signal_exit_handler);
        signal(SIGINT, signal_exit_handler);
    
        // ignore SIGPIPE
        signal(SIGPIPE, SIG_IGN);
    
        signal(SIGBUS, signal_crash_handler);     // 总线错误
        signal(SIGSEGV, signal_crash_handler);    // SIGSEGV,非法内存访问
        signal(SIGFPE, signal_crash_handler);       // SIGFPE,数学相关的异常,如被0除,浮点溢出,等等
        signal(SIGABRT, signal_crash_handler);     // SIGABRT,由调用abort函数产生,进程非正常退出
    
        return 0;
    }
    

      

    这个例子里面其实是将异常退出处理和正常退出处理结合起来了。对于SIGTERM(即kill进程)和SIGINT(即ctrl-c结束前台进程),我们当做是正常退出,在其信号处理函数里面,直接调用了exit(0),而exit(0)又会被server_on_exit捕获到。对于异常退出也是类似,只是调用了exit(-1)表示是异常的。同时异常退出我们会打印出当前的进程堆栈信息,server_backtrace的实现下一篇再说。另外注意的是SIGKILL信号是无法捕获的。而调用abort导致的退出,也是通过SIGABRT信号捕获到进行处理了。其他几种异常退出的信号也是比较常见,一并捕获到进行处理。这样对于异常退出,我们即可统一的log堆栈信息,又可直接继续正常退出时的处理流程了。

  • 相关阅读:
    《大数据——大价值、大机遇、大变革》试读
    div+csS中的一些技巧和浏览器兼容的办法
    js正则表达式
    布局 IE haslayout
    几个好的网站
    ie6 几个li上下排列会闪动的问题,嵌套div—外层div内层div都设置背景颜色,内层div背景色不显示的问题
    live()解决Jquery采用append添加的元素事件无效和获取不到添加元素的值
    SQL语句写返回一天内的纪录,得到一周内星期几的时间
    网易邮箱添加附件功能原理浅析转
    实体类序列化
  • 原文地址:https://www.cnblogs.com/whwywzhj/p/7800819.html
Copyright © 2011-2022 走看看