2016-09-05 10 views
1

Я запускаю свою программу на Mac OS. Часть моей программы следующая. Этот код хорошо работает по сигналу sigint, но не может работать с сигналом сигкилла.В C, linux, о сигнале kill и sleep() в цикле

void sigkill(int sig){ 
    /*some code neglected*/ 
    exit(0); 
} 
void sigint(int sig){ 
    flag=1; 
} 

void alive(void) { 
    signal(SIGINT, sigint); 
    signal(SIGKILL, sigkill); 
    alarm(10); 
    while(1){ 
     //printf("%d\n",flag); 
     sleep(1); 
     if(flag==1){ 
      printf("no\n"); 
      flag=0; 
     } 
    } 
} 

У меня есть четыре вопроса:

  1. На первых я не писал sleep(1), он может ввести функцию SIGINT(), и изменить значение флага, я могу видеть из Printf. Однако, как я и ожидал, нет «нет».

  2. После того, как я добавил функцию сна, он работает хорошо. Я предполагаю, что цикл while проверяет флаг каждые 1 секунду и выводит «нет», если флаг = 1. Однако, кажется, что «нет» выход каждый раз, когда я нажимаю ctrl + c. Почему он не ждет одну секунду?

  3. Вопрос: «Вы не должны использовать« sleep() »для ожидания 10 секунд. Используйте будильник() в сочетании с циклом». Я хочу знать, как реализовать это без сна().

  4. Команда kill не может вызвать функцию sigkill, как исправить это?

+3

Вы не можете использовать ловушку 'SIGKILL' - период. Вы не можете установить ловушку для 'SIGKILL'. Тоже 'SIGSTOP', кстати. –

+0

Знаете ли вы, как реализовать его без сна()? –

+0

Смешивание 'alarm()' и 'sleep()' не на 100% надежное. Вы можете использовать 'alarm()' и 'pause()' - 'pause()' только возвращается, когда он прерывается, и обработчик сигнала возвращается. Вы можете использовать 'select()' и 'poll()' и варианты, специфичные для платформы, для выполнения второстепенных снов. Вы можете использовать 'nanosleep()' и 'usleep()' для выполнения спящего режима nano-second и micro-second (хотя точность, как правило, не так хороша, как разрешение). Если вы будете выглядеть тяжело, там, вероятно, будет миллисекунда. –

ответ

3
  1. В общем, сигналы могут быть только «захватываются» приложения, когда это делает системный вызов в ядро. Если вы делаете простой while(1) { if (flag==1){...} }, это никогда не вызовет ядро. Теоретически, когда вы делаете свой внешний printf в цикле while(1), который должен вызывать ядро, и поэтому сигнал может быть пойман.
  2. sleep() прерван любым сигналом. Проверьте страницу руководства для sleep(3).
  3. проверить страницу руководства для alarm(2).
  4. Вы не можете изменить обработчик сигнала для SIGKILL или для SIGSTOP. Эти сигнальные эффекты жестко закодированы в ядре. От sigaction(2):

    Signum определяет сигнал и может быть любой действительный сигнал кроме SIGKILL и SIGSTOP.

    Команда kill без аргументов не генерирует сигнал SIGKILL; он генерирует SIGTERM.

+0

Я не совсем понимаю третий ответ. Как реализовать его без сна? –

+1

На странице man для 'alarm (2)': 'alarm() организует передачу сигнала SIGALRM в процесс в секундах секунд.' –