Описание
Доступ к разделяемым данным в обработчике сигнала происходит, когда вы получаете доступ или изменяете общий объект в обработчике сигнала.
Риск
Когда вы задаете функцию-обработчик сигнала, чтобы получить доступ или изменить общий объект, доступы к обработчику, или изменяет общий объект, когда он получает сигнал. Если другая функция уже получает доступ к общему объекту, эта функция вызывает состояние состязания и может оставить данные в противоречивом состоянии.
Фиксация
Чтобы получить доступ или изменить общие объекты в обработчике сигнала, проверяйте, что объекты без блокировок атомарный, или, если они - целые числа, объявляют их как volatile sig_atomic_t
.
Пример - int
Переменный доступ в обработчике сигнала
#include <signal.h>
#include <stdlib.h>
#include <string.h>
/* declare global variable. */
int e_flag;
void sig_handler(int signum)
{
/* Signal handler accesses variable that is not
of type volatile sig_atomic_t. */
e_flag = signum;
}
int func(void)
{
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
/* Handle error */
abort();
}
/* Program code */
if (raise(SIGINT) != 0)
{
/* Handle error */
abort();
}
/* More code */
return 0;
}
В этом примере, sig_handler
доступы e_flag
, переменная типа int
. Параллельный доступ другой функцией может оставить e_flag
в противоречивом состоянии.
Коррекция — объявляет переменную типа volatile sig_atomic_t
Прежде чем вы получите доступ к совместно используемой переменной от обработчика сигнала, объявите переменную с типом volatile sig_atomic_t
вместо int
. Вы можете безопасно переменные доступа этого типа асинхронно.
#include <signal.h>
#include <stdlib.h>
#include <string.h>
/* Declare variable of type volatile sig_atomic_t. */
volatile sig_atomic_t e_flag;
void sig_handler(int signum)
{
/* Use variable of proper type inside signal handler. */
e_flag = signum;
}
int func(void)
{
if (signal(SIGINT, sig_handler) == SIG_ERR)
{
/* Handle error */
abort();
}
/* Program code */
if (raise(SIGINT) != 0)
{
/* Handle error */
abort();
}
/* More code */
return 0;
}