Как функция signal() работает в C с SIGINT

#include <stdio.h>  
#include <signal.h>

void f( int );

int main () {
    int i ;
    signal ( SIGINT , f) ;
    for (i =0; i <5; i ++) {
        printf ( " hello \n " ) ;
        sleep (10) ;
    }
}

void f( int signum ){
    //signal ( SIGINT , f) ;
    printf ( " OUCH !\n ") ;
}

Я пытаюсь научиться обрабатывать сигналы в c. В приведенном выше коде я не мог понять, как работает этот сигнал функции. Я понимаю, что когда я выполняю этот код, когда я нажимаю control-c, функция f будет выполняться и прервет цикл. Но когда я нажимаю повторно и быстро, команда control-c sleep не будет выполняться. Почему?


person seinta    schedule 11.06.2014    source источник
comment
Это зависит от операционной системы. В Linux прочитайте signal(7), затем Продвинутое программирование для Linux   -  person Basile Starynkevitch    schedule 11.06.2014
comment
Вы спрашиваете, почему sleep не будет выполняться после сигнала?   -  person egur    schedule 11.06.2014
comment
На странице руководства POSIX для signal() говорится, что новые приложения должны используйте sigaction() вместо signal().   -  person pmg    schedule 11.06.2014


Ответы (3)


При получении сигнала вызов sleep() прерывается.

Чтобы визуализировать это, измените код следующим образом:

unsigned seconds_left = 10;
while (0 < (seconds_left = sleep(seconds_left)))
{
  printf("Woke up with still %us to sleep, falling asleep again ...\n", seconds_left
}

Из man sleep (курсив автора). ):

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Ноль, если запрошенное время истекло, или количество секунд, оставшееся до ожидания, если вызов был прерван обработчиком сигнала.

person alk    schedule 11.06.2014

Коротко о том, что функция sleep() будет прервана и вернется, когда будет пойман сигнал. Возвращаемое значение sleep скажет вам, сколько секунд осталось до того, как он должен был вернуться, если бы он не был прерван.

Определенные функции прерываются и возвращаются при перехвате сигнала. Это зависит от вашей платформы и от того, как установлен обработчик сигналов. (А в Linux это будет зависеть от флагов компиляции, используемых при установке обработчика сигналов с помощью signal(). См. документацию здесь и здесь< /а>)

person nos    schedule 11.06.2014

В сигнале обработчик находится в точке перехвата. Он позвонит, когда придет сигнал. После вызова он начинает выполняться со следующей строки, с которой он был вызван.

Итак, в вашем примере, когда поступает сигнал (SIGINT), он подключается к обработчику f , после завершения f он снова войдет в цикл.

(Обратите внимание, что из обработчика f нет выхода или прерывания, только когда он вернется к следующей строке выполнения в цикле)

person Sandeep_black    schedule 26.03.2017