std::signal
| Определён в заголовке <csignal>
|
||
/*signal-handler*/* signal( int sig, /*signal-handler*/* handler );
|
(1) | |
extern "C" using /*signal-handler*/ = void(int);
|
(2) | (только для пояснения*) |
Изменяет обработку сигнала sig. В зависимости от значения handler, сигнал может игнорироваться, установлен на обработку по умолчанию или обрабатываться пользовательской функцией, вызываемой как (*handler)(sig).
Когда обработчик сигнала установлен на функцию и происходит сигнал, определяется реализацией, будет ли 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 (C linkage) и, как правило, использовать только возможности общего подмножества языков C и C++. Тем не менее распространённые реализации позволяют использовать функцию со связыванием C++ в качестве обработчика сигнала.
Пример
#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
|
|