2016-10-02 1 views
0

есть SIGINT обработчик. Он устанавливает переменную для всей программы: errflag. Когда я делаю select() и он прерван через SIGINT, я проверяю errflag, чтобы узнать, есть ли он SIGINT (имеют собственную константу, назначенную errflag). Однако обработчик может опоздать и errflag еще не установлен. Как отложить обработку до разрешения обработчика на errflag? Или как это реализовать правильно?Как обеспечить завершение обработки обработчика сигнала и только затем продолжить программу?

Кроме того, в одном пути кода select() возвращает -1 на Ctrl-C, errno является EINTR. Здесь обработчик никогда не опаздывает. На другом пути select() возвращает -1, errno также EINTR, но обработчик выводит сообщение журнала немного позже и опаздывает, мои проверки errflag уже выполнены.

+0

Как указано в первом ответе, прерывание останавливает текущую обработку и запускает обработчик, и, если обработчик возвращает, либо перезапускает системный вызов, либо прерывает его с помощью 'errno', установленного в' EINTR'. Используете ли вы 'signal()' или 'sigaction()'? Без вашего кода будет трудно понять, что происходит не так, но ваша интерпретация, что обработчик сигнала может быть отложен, в основном неправильна. С помощью 'sigaction()' вы можете заблокировать один сигнал, в то время как другой сигнал обрабатывается 'sa_mask', но заблокированный сигнал будет доставлен при возврате первого обработчика. –

+0

@JonathanLeffler: да, вы правы, сигнал вручную откладывается механизмом очереди, а обработчик рано возвращается, не отлаживал печать до этого и интерпретировал вызов из очереди как первый, поздний вызов. – Itzie

+0

Итак, у вас был обработчик сигналов с двумя или более маршрутами выхода, и у одного был диагностический отпечаток, а другой нет? Легко сделано - но и что-то, на что можно смотреть. Это может привести к серьезной неправильной интерпретации результатов. Одним из (немногих) достоинств программирования с одиночной записью и одним выходом является то, что вы не сталкиваетесь с этой проблемой! –

ответ

3

Однако обработчик может опоздать и errflag еще не установлен.

Er, что? Нет, это не может быть «поздно». Здесь что-то еще не так.

Обработчики сигналов прерывают нормальный поток программы - когда SIGINT принимается, ваш обработчик работает, и поток управления освобождается только от остальной части вашей программы, когда выходной сигнал обработчика сигнала выходит.

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

Что нужно помнить, так это то, что printf() небезопасно использовать в обработчиках сигналов, так как он может использовать глобальные буферы, которые могут быть оставлены в противоречивом состоянии во время обработки сигнала. Generally speaking, very few things are safe to do during a signal handler besides setting volatile global variables or exiting. Попытка использовать printf() в обработчике сигнала может привести к непоследовательным, запутывающим результатам; выход не должен использоваться как надежный показатель того, что на самом деле произошло в вашей программе!

+0

Спасибо, я проверил, и обработчик вызван мгновенно, есть только механизм очередей, и сигнал как-то снова запущен из очереди позже. У меня было отладочное сообщение позже, после возможной очереди, и не видел моментального вызова обработчика сигнала. – Itzie

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