signal()覆盖其他信号处理程序

时间:2012-05-22 12:04:48

标签: c++ dll sigint

signal()函数是否会覆盖进程可能设置的其他信号调用?即如果进程设置了SIGINT处理程序,并且DLL调用signal(SIGINT,xxx)来处理自己的终止代码,原始SIGINT处理程序是否会被禁用?

2 个答案:

答案 0 :(得分:8)

signal()来电:

  1. 安装您指定为新信号处理程序的处理程序,并
  2. 告诉你旧处理程序是什么。
  3. 将调用新处理程序而不是旧处理程序。如果你想链接它们,你需要做类似的事情:

    typedef void (*Handler)(int signum);
    
    static Handler old_int_handler = SIG_IGN;
    
    static void int handler(int signum)    /* New signal handler */
    {
        ...do your signal handling...
        if (old_int_handler != SIG_IGN && old_int_handler != SIG_DFL)
            (*old_int_handler)(signum);
    }
    
    static void set_int_handler(void)  /* Install new handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old != SIG_IGN)
        {
            old_int_handler = old;
            signal(SIGINT, int_handler);
        }
    }
    
    static void rst_int_handler(void)    /* Restore original handler */
    {
        Handler old = signal(SIGINT, SIG_IGN);
        if (old == int_handler)
        {
            signal(SIGINT, old_int_handler);
            old_int_handler = SIG_IGN;
        }
    }
    
    ...in another function...
    {
        ...
        set_int_handler();
        ...
        rst_int_handler();
        ...
    }
    

    如果忽略中断,则会忽略它们。如果用户定义的中断处理程序正在处理中断,则会调用您的信号处理代码和原始信号处理代码。

    请注意,来自adviceChristian.K关于不处理DLL(共享库)中的信号也是相关且有效的。上面的描述假设您决定忽略该建议。

答案 1 :(得分:2)

这不是您的问题的“字面”答案,而是建议:您不应该在DLL中执行此操作。

使用DLL的应用程序出乎意料并且经常令人讨厌。 DLL(通常)应该是“被动的”,并且只为应用程序提供调用函数。

因此,请提供DLL中的公共函数,以便应用程序调用,例如MyDllCleanup()。然后让应用程序决定它如何调用该函数(通过信号处理程序或其他)。顺便说一下,初始化也是如此:而不是依赖于DllMain(或_init / _finilibdl在UNIX上)为应用程序提供显式函数来调用。