signal() перезаписывает другие обработчики сигналов

Переписывает ли функция signal() другие вызовы сигналов, которые мог настроить процесс? т.е. если обработчик SIGINT был установлен процессом, а DLL вызывает signal(SIGINT,xxx) для обработки собственного кода завершения, отключается ли исходный обработчик SIGINT?


person Qix - MONICA WAS MISTREATED    schedule 22.05.2012    source источник
comment
Я не верю, что библиотеки DLL и сигналы находятся в одной операционной системе, приятель.   -  person Puppy    schedule 22.05.2012
comment
@DeadMG: Однако вы ошибаетесь, Windows поддерживает SIGINT, msdn.microsoft.com/en-us/library/xdkz3x12(VS.71).aspx   -  person Hasturkun    schedule 22.05.2012
comment
@DeadMG: SIGINT нет, другие есть. msdn.microsoft.com/en-us/ библиотека/xdkz3x12%28v=vs.110%29.aspx   -  person CB Bailey    schedule 22.05.2012
comment
Поскольку signal() требуется стандартом C (C89), MSVC должен его поддерживать. Семантика может быть ограничена, но ее необходимо поддерживать.   -  person Jonathan Leffler    schedule 22.05.2012


Ответы (2)


Вызов signal():

  1. Устанавливает обработчик, указанный вами как новый обработчик сигнала, и
  2. Сообщает вам, каким был старый обработчик.

Новый обработчик будет вызываться вместо старого. Если вы хотите связать их, вам нужно сделать что-то вроде:

    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;
        }
    }

    void another_function()
    {
        /* ... */
        set_int_handler();
        /* ... */
        rst_int_handler();
        /* ... */
    }

Если прерывания игнорировались, это сохраняет их игнорирование. Если прерывания обрабатывались определяемым пользователем обработчиком прерываний, то это вызывает ваш код обработки сигналов и исходный код обработки сигналов.

Обратите внимание, что совет от Christian.K о том, что нельзя обрабатывать сигналы в DLL (разделяемой библиотеке), также актуален и актуален. Описание выше предполагает, что вы решили проигнорировать этот совет.

person Jonathan Leffler    schedule 22.05.2012

Это не «буквальный» ответ на ваш вопрос, а рекомендация: вам не следует делать это в DLL.

Это неожиданно и часто раздражает приложение, использующее DLL. DLL должна (обычно) быть «пассивной» и предоставлять только функции для вызова приложения.

Поэтому лучше предоставьте общедоступную функцию из вашей DLL, которую приложения должны вызывать, например. MyDllCleanup(). Затем позвольте приложению решить, как оно вызывает эту функцию (через обработчик сигнала или другое). Кстати, то же самое касается инициализации: вместо того, чтобы полагаться на DllMain (или _init/_fini с libdl в UNIX), предоставьте явные функции для вызова приложений.

person Christian.K    schedule 22.05.2012
comment
Это верно; однако DLL вводится. - person Qix - MONICA WAS MISTREATED; 22.05.2012
comment
Хм, вы внедряете DLL в произвольные процессы? Или вы знаете внутреннюю работу ваших целевых процессов. Потому что в противном случае вы рискуете и их стабильностью. В общем, сигналы и потоки плохо сочетаются. Кроме того, SIGINT не поддерживается ни для одного приложения Win32. . Когда происходит прерывание CTRL+C, операционные системы Win32 создают новый поток специально для обработки этого прерывания. Это может привести к тому, что однопоточное приложение, такое как приложение в UNIX, станет многопоточным, что приведет к неожиданному поведению.. - person Christian.K; 23.05.2012
comment
Да; Я понимаю, когда sigint поднимается и не поднимается. - person Qix - MONICA WAS MISTREATED; 23.05.2012