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 в случае ошибки (в некоторых реализациях установка обработчика сигнала может быть отключена).
Обработчик сигнала
На пользовательскую функцию, установленную в качестве обработчика сигнала, накладываются следующие ограничения.
| Если обработчик сигнала вызван НЕ в результате
| (до C++17) |
| Обычная свободная от блокировок атомарная операция — это вызов функции
Поведение не определено, если обработчик сигнала выполняет любое из следующих действий:
| (начиная с C++17) |
Если пользовательская функция возвращает управление при обработке SIGFPE, SIGILL, SIGSEGV или любого другого определяемого реализацией сигнала, указывающего на вычислительное исключение, поведение не определено.
Если обработчик сигнала вызван в результате std::abort или std::raise (синхронный сигнал), поведение не определено, если обработчик сигнала вызывает std::raise.
| При входе в обработчик сигнала состояние среды вычислений с плавающей точкой и значения всех объектов не определены, за исключением
При возврате из обработчика сигнала значение любого изменённого им объекта, который не является volatilestd::sig_atomic_t или свободным от блокировок | (до C++14) | ||
| Вызов функции Если обработчик сигнала выполняется в результате вызова Два обращения к одному и тому же объекту типа volatilestd::sig_atomic_t не приводят к гонке данных, если оба происходят в одном потоке, даже если одно или несколько обращений выполняются в обработчике сигнала. Для каждого вызова обработчика сигнала вычисления, выполняемые потоком, вызвавшим обработчик, можно разделить на две группы A и B так, чтобы ни одно вычисление из B не предшествовало по отношению happens-before вычислениям из A, а вычисления таких объектов volatilestd::sig_atomic_t принимали значения так, как если бы все вычисления в A предшествовали по отношению happens-before выполнению обработчика сигнала, а выполнение обработчика сигнала предшествовало по отношению happens-before всем вычислениям в B. | (начиная с C++14) |
Примечания
POSIX требует, чтобы signal был потокобезопасным, и определяет список безопасных для асинхронных сигналов библиотечных функций, которые можно вызывать из любого обработчика сигнала.
Предполагается, что обработчики сигналов имеют связывание C и в целом используют только возможности общего подмножества C и C++. Однако распространённые реализации допускают использование функции со связыванием C++ в качестве обработчика сигнала.
Пример
#include <csignal>
#include <iostream>
namespace
{
volatile std::sig_atomic_t gSignalStatus;
}
void signal_handler(int signal)
{
gSignalStatus = signal;
}
int main()
{
// Install a signal handler
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++.
| Отчёт об ошибке | Применён к | Опубликованное поведение | Правильное поведение |
|---|---|---|---|
| LWG 3756 | C++17 | не было ясно, является ли std::atomic_flag безопасным для сигналов | является |
См. также
| вызывает обработчик указанного сигнала (функция) |
|
|
(C++11) | барьер между потоком и обработчиком сигнала, выполняемым в том же потоке (функция) |
Документация C для signal |
|
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/utility/program/signal