std:: signal
|
Определено в заголовочном файле
<csignal>
|
||
|
/* signal-handler */
*
signal
(
int
sig,
/* signal-handler */
*
handler
)
;
|
(1) | |
|
extern
"C"
using
/* signal-handler */
=
void
(
int
)
;
|
(2) | ( только для демонстрации* ) |
Изменяет обработку сигнала sig . В зависимости от handler , сигнал может быть проигнорирован, установлен в значение по умолчанию или обработан пользовательской функцией.
Когда обработчик сигнала установлен на функцию и возникает сигнал, определяется реализацией, будет ли std :: signal ( sig, SIG_DFL ) выполнена непосредственно перед запуском обработчика сигнала. Кроме того, реализация может предотвращать возникновение некоторого определённого реализацией набора сигналов во время выполнения обработчика сигнала.
Для некоторых сигналов реализация может вызывать std :: signal ( sig, SIG_IGN ) при запуске программы. Для остальных сигналов реализация должна вызывать std :: signal ( sig, SIG_DFL ) .
(Примечание: POSIX ввела
sigaction
для стандартизации этих определяемых реализацией поведений)
Содержание |
Параметры
| sig | - |
сигнал, для которого устанавливается обработчик. Может быть реализационно-определенным значением или одним из следующих значений:
|
||||||
| handler | - |
обработчик сигнала. Должен быть одним из следующих:
|
Возвращаемое значение
Предыдущий обработчик сигнала при успехе или SIG_ERR при неудаче (установка обработчика сигнала может быть отключена в некоторых реализациях).
Обработчик сигналов
На пользовательскую функцию, устанавливаемую в качестве обработчика сигнала, накладываются следующие ограничения.
|
Если обработчик сигнала вызывается НЕ в результате std::abort или std::raise (асинхронный сигнал), поведение не определено, если
|
(until C++17) |
|
Простая операция с атомарным доступом без блокировок — это вызов функции f из <atomic> или <stdatomic.h> (since C++23) , такой что:
Поведение не определено, если любой обработчик сигнала выполняет любое из следующего:
|
(since C++17) |
Если пользовательская функция возвращает управление при обработке SIGFPE , SIGILL , SIGSEGV или любого другого определяемого реализацией сигнала, указывающего на вычислительное исключение, поведение не определено.
Если обработчик сигнала вызывается в результате std::abort или std::raise (синхронный сигнал), поведение не определено, если обработчик сигнала вызывает std::raise .
|
При входе в обработчик сигнала состояние среды с плавающей запятой и значения всех объектов не определены, за исключением:
При возврате из обработчика сигнала значение любого объекта, измененного обработчиком сигнала, который не является volatile std:: sig_atomic_t или lock-free std::atomic , является неопределенным. |
(until C++14) | ||
|
Вызов функции
Если обработчик сигнала выполняется в результате вызова
std::raise
(синхронно), то выполнение обработчика
упорядочено-после
вызова
Два обращения к одному и тому же объекту типа volatile std:: sig_atomic_t не приводят к гонке данных, если оба происходят в одном и том же потоке, даже если одно или более происходит в обработчике сигнала. Для каждого вызова обработчика сигнала вычисления, выполняемые потоком, вызывающим обработчик сигнала, могут быть разделены на две группы A и B, такие что никакие вычисления в B не происходят-до вычислений в A, и вычисления таких volatile std:: sig_atomic_t объектов принимают значения, как если бы все вычисления в A происходили-до выполнения обработчика сигнала и выполнение обработчика сигнала происходило-до всех вычислений в B. |
(since C++14) |
Примечания
POSIX требует, чтобы
signal
был потокобезопасным, и
определяет список асинхронно-сигнально-безопасных библиотечных функций
, которые могут вызываться из любого обработчика сигналов.
Ожидается, что обработчики сигналов имеют C linkage и, как правило, используют только возможности из общего подмножества C и C++. Однако распространённые реализации позволяют использовать функцию с C++ linkage в качестве обработчика сигнала.
Пример
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // Установка обработчика сигнала std::signal(SIGINT, signal_handler); std::cout << "SignalValue: " << gSignalStatus << '\n'; std::cout << "Sending signal: " << SIGINT << '\n'; std::raise(SIGINT); std::cout << "SignalValue: " << gSignalStatus << '\n'; }
Возможный вывод:
SignalValue: 0 Sending signal: 2 SignalValue: 2
Ссылки
- Стандарт C++23 (ISO/IEC 14882:2024):
-
- 17.13.5 Обработчики сигналов [support.signal]
- Стандарт C++20 (ISO/IEC 14882:2020):
-
- 17.13.5 Обработчики сигналов [support.signal]
- Стандарт C++17 (ISO/IEC 14882:2017):
-
- 21.10.4 Обработчики сигналов [support.signal]
Отчеты о дефектах
Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Applied to | Behavior as published | Correct behavior |
|---|---|---|---|
| LWG 3756 | C++17 | it was unclear whether std::atomic_flag is signal-safe | it is |
Смотрите также
|
запускает обработчик сигнала для определенного сигнала
(функция) |
|
|
(C++11)
|
барьер между потоком и обработчиком сигнала, выполняемым в том же потоке
(функция) |
|
Документация C
для
signal
|
|