2013-12-04 3 views
0

Я хочу, чтобы во время отправки сигнала выходил из цикла while. Я не уверен, как это сделать без использования глобальной переменной или записи в файл. Будет ли мой лучший выбор использовать семафор?Проверка последнего сигнала, отправленного в ваше приложение

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

void random() 
{ 
    printf("random!"); 
} 

int main(void) { 
    signal(SIGINT, random); 

    // I want this while loop to break if random executes 
    while (1) 
    { 
     pause(); 
    } 
    // do more stuff after loop 

    return 0; 
} 
+1

В этом конкретном случае работа с удалением цикла будет работать. –

ответ

1

pause блокирует до получения сигнала, который вызывает обработчик сигнала, поэтому вы можете просто добавить break; после pause();, чтобы выйти из цикла. Таким образом, вы можете полностью избавиться от цикла.

Если вы хотите сделать, это НЕ ждать, но вместо этого цитировать что-то делать и только выходить, когда возникает сигнал, вы не можете использовать pause. Очевидным способом является использование глобальной переменной, но вы говорите, что хотите этого избежать. Альтернатива, которая на самом деле не какой-либо простой заключается в использовании sigprocmask/sigpending вместо обработчика сигнала:

int main() 
{ 
    setset_t signals; 
    sigemptyset(&signals); 
    sigaddset(&signals, SIGINT); 
    sigprocmask(SIG_BLOCK, &signals, 0); /* block SIGINT */ 

    while (1) { 
     /* do stuff */ 
     sigpending(&signals); 
     if (sigismember(&signals, SIGINT)) { 
      /* got a SIGINT */ 
      break; 
     } 
    } 
} 
0

Ваша основная функция не делает ничего после цикла, кроме выхода. Я понимаю, что это может быть упрощенный код, чтобы задать вопрос. Но если вы на самом деле ничего не делать после того, как петли вы хотите вырваться из, а затем просто изменить функцию обработчика значи к этому:

void random(int sig) 
{ 
    printf("random!"); 
    exit(sig); // or exit(0); as in your main() 
} 

С другой стороны, если вам нужно общаться между random (обработчиком) и main, то почему вы неохотно используете переменную?

+0

Я бы хотел, чтобы программа продолжала выполнение после цикла, спасибо. – user1766555

0

Правильный ответ действительно зависит от того, что вы собираетесь делать в цикле. Я предполагаю, что pause() - это просто поддельный код, поскольку это не полезно.

Если цикл цикла событий, который ждет с select или poll, вы можете переключиться на pselect (стандарт в POSIX) или ppoll (нестандартное расширение, но лучше, так как select API так плохо) то, что также позволит вы ждете сигналов. Но вы все еще придерживаетесь того, как получить уведомление о том, что сигнал произошел. Только с одним сигналом вы можете использовать тот факт, что EINTR был возвращен, чтобы сделать вывод, что SIGINT произошло, но это не работает так хорошо, если могут быть и другие обработчики сигналов. В основном обработка сигналов в основном глобальная, и как таковые глобальные переменные/глобальное состояние должны быть задействованы в некотором роде. Вы можете сохранить флаг, что сигнал произошел в глобальной переменной и каждый раз проверять его pselect/ppoll, или вы можете просто придерживаться простого стандарта poll и использовать self-pipe trick, поскольку вам нужно что-то делать с глобальным состоянием в своем обработчик сигнала в любом случае.

Если ваш цикл не ждет событий, но постоянно вращается (например, вычислительный цикл), то просто блокирует сигнал (с sigprocmask или pthread_sigmask) и периодически проверять для него с sigispending или sigwaitinfo простым решением, которое не требует любой код в обработчике сигналов.

Смежные вопросы