Лекции по курсу "Системное программирование для UNIX". Литвинов Д.Г. - 25 стр.

UptoLike

Составители: 

25
int
main (void)
{
signal (SIGALRM, catch_alarm);
alarm (2);
while (keep_going)
do_stuff ();
return EXIT_SUCCESS;
}
Обработчики второго типа обычно используются для выполнения некоторых
завершающих действий при критических ошибках. Наилучший путь для прекращения
выполнения процессавызвать тот же сигнал с определенным действием по
умолчанию. Например,
volatile sig_atomic_t fatal_error_in_progress = 0;
void
fatal_error_signal (int sig)
{
if (fatal_error_in_progress)
raise (sig);
fatal_error_in_progress = 1;
...
signal (sig, SIG_DFL);
raise (sig);
}
Если запущен обработчик для конкретного сигнала, то этот сигнал блокируется
до тех пор, пока работа обработчика не будет завершена. Тем не менее, работа
обработчика может быть прервана приходом какого-либо другого сигнала. Для того,
чтобы избежать этого нужно использовать поле sa_mask структуры sigaction, чтобы
указать какие сигналы будут заблокированы в процессе выполнения обработчика.
При написании обработчиков сигналов следует стремиться к минимизации его
кода и сокращению времени выполнения. Критическим местом могут стать структуры
данных, с которыми работает обработчик. Необходимо придерживаться следующих
принципов:
если обработчику необходимо работать с глобальной переменной,
определенной в программе, то она должна быть определена как volatile, что
говорит компилятору о возможности изменения ее асинхронно;
если в обработчике вызывается какая-либо функция, убедитесь, что она
является повторно входимой или в том, что сигнал не может прервать
выполнение этой функции.
Элементарный доступ к данным
При написании обработчиков существует проблема обращения к
неэлементарным данным (объектам в памяти, доступ к которым может быть
осуществлен лишь при выполнении нескольких операций с данными). В случае
поступления сигнала в момент модификации содержимого объекта, его значение может
стать непредсказуемым. Например,
#include <signal.h>
#include <stdio.h>
             int
             main (void)
             {
               signal (SIGALRM, catch_alarm);

                 alarm (2);

                 while (keep_going)
                   do_stuff ();

                 return EXIT_SUCCESS;
             }
       Обработчики второго типа обычно используются для выполнения некоторых
завершающих действий при критических ошибках. Наилучший путь для прекращения
выполнения процесса – вызвать тот же сигнал с определенным действием по
умолчанию. Например,
             volatile sig_atomic_t fatal_error_in_progress = 0;

             void
             fatal_error_signal (int sig)
             {
               if (fatal_error_in_progress)
                 raise (sig);
               fatal_error_in_progress = 1;

                 ...

                 signal (sig, SIG_DFL);
                 raise (sig);
             }
        Если запущен обработчик для конкретного сигнала, то этот сигнал блокируется
до тех пор, пока работа обработчика не будет завершена. Тем не менее, работа
обработчика может быть прервана приходом какого-либо другого сигнала. Для того,
чтобы избежать этого нужно использовать поле sa_mask структуры sigaction, чтобы
указать какие сигналы будут заблокированы в процессе выполнения обработчика.
        При написании обработчиков сигналов следует стремиться к минимизации его
кода и сокращению времени выполнения. Критическим местом могут стать структуры
данных, с которыми работает обработчик. Необходимо придерживаться следующих
принципов:
•          если обработчику необходимо работать с глобальной переменной,
           определенной в программе, то она должна быть определена как volatile, что
           говорит компилятору о возможности изменения ее асинхронно;
•          если в обработчике вызывается какая-либо функция, убедитесь, что она
           является повторно входимой или в том, что сигнал не может прервать
           выполнение этой функции.

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

       #include 
       #include 



                                                                                 25