Пространства имён
Варианты
Действия

std::signal

Материал из cppreference.com
< cpp‎ | utility‎ | program
 
 
Библиотека утилит
Языковая поддержка
Поддержка типов (базовые типы, RTTI)
Макросы тестирования функциональности библиотеки (C++20)    
Управление динамической памятью
Программные утилиты
Поддержка сопрограмм (C++20)
Вариативные функции
Трёхстороннее сравнение (C++20)
(C++20)
(C++20)(C++20)(C++20)(C++20)(C++20)(C++20)
Общие утилиты
Дата и время
Функциональные объекты
Библиотека форматирования (C++20)
(C++11)
Операторы отношения (устарело в C++20)
Целочисленные функции сравнения
(C++20)(C++20)(C++20)    
(C++20)
Операции обмена и типа
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
Общие лексические типы
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)
Элементарные преобразования строк
(C++17)
(C++17)
 
Утилиты поддержки программ
Прерывание программы
(C++11)
(C++11)
Недостижимый поток управления
Взаимодействие с окружением
Сигналы
Типы сигналов
Нелокальные переходы
Типы
 
Определено в заголовочном файле <csignal>
/*обработчик-сигнала*/* signal(int sig, /*обработчик-сигнала*/* handler);
(1)
extern "C" using /*обработчик-сигнала*/ = 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_DFL. Обработчик сигнала по умолчанию.
  • макрос SIG_IGN. Сигнал игнорируется.
  • указатель на функцию. При этом сигнатура функции должна быть следующей:
extern "C" void fun(int sig);
или
void fun(int sig);
(начиная с C++17)


[править] Возвращаемое значение

Возвращается предыдущий обработчик сигнала или SIG_ERR в случае ошибки (установка обработчиков сигналов может быть отключена на некоторых реализациях)

[править] Обработчик сигнала

На пользовательскую функцию, устанавливаемую в качестве обработчика сигнала, накладываются следующие ограничения.

Если обработчик сигнала вызывается НЕ в результате std::abort или std::raise (асинхронный сигнал), поведение не определено, если

  • обработчик сигнала вызывает любую функцию из стандартной библиотеки, кроме
  • std::abort
  • std::_Exit
  • std::quick_exit
  • std::signal, где первым аргументом является номер обрабатываемого в данный момент сигнала (асинхронный обработчик может перерегистрировать себя, но не другие сигналы).
  • обработчик сигнала ссылается на любой объект со статической длительностью хранения, который не является std::atomic или (начиная с C++11)volatile std::sig_atomic_t.
(до C++17)

Простая атомарная операция без блокировок это вызов функции f из <atomic> или <stdatomic.h> (начиная с C++23), так что:

  • f это функция std::atomic_is_lock_free,
  • f это функция-элемент is_lock_free (например, std::atomic::is_lock_free()),
  • f является нестатической функцией-элементом std::atomic_flag,
  • f является функцией, не являющейся элементом, и первый параметр f имеет тип cv std::atomic_flag*,
  • f это нестатическая функция-член, вызываемая для объекта obj, так что obj.is_lock_free() возвращает true, или
  • f не является функцией-элементом, и для каждого аргумента указателя на атомарный arg, переданного в f, std::atomic_is_lock_free(arg) даёт true.

Поведение не определено, если какой-либо обработчик сигнала выполняет одно из следующих действий:

  • за исключением простых атомарных операций без блокировок и следующих сигналобезопасных функций (отметим, в частности, что динамическое размещение не является сигналобезопасным):
  • доступ к объекту с потоковой длительностью хранения
  • выражение dynamic_cast
  • выражение throw
  • вход в блок try, включая try-блок функции
  • инициализацию статической переменной, которая выполняет динамическую нелокальную инициализацию (включая отложенную до первого использования ODR)
  • ожидание завершения инициализации любой переменной со статической длительностью хранения из-за того, что другой поток одновременно инициализирует её
(начиная с C++17)

Если пользовательская функция выполнила возврат, когда случился сигнал SIGFPE, SIGILL, SIGSEGV или любой другой определённый реализацией сигнал, определяющий ошибку вычисления, то поведение будет не определено.

Если обработчик сигнала вызван в результате вызова std::abort или std::raise (синхронный сигнал), то поведение будет не определённым, если обработчик сигнала вызовет std::raise.

При входе в обработчик сигнала состояние среды с плавающей запятой и значения всех объектов не указаны, за исключением

(начиная с C++11)

При возврате из обработчика сигнала значение любого объекта, изменённого обработчиком сигнала, который не является volatile std::sig_atomic_t или неблокируемым std::atomic, является неопределённым.

(до C++14)

Вызов функции signal() синхронизируется с любым результирующим вызовом обработчика сигнала.

Если обработчик сигнала выполняется в результате вызова std::raise (синхронно), то выполнение обработчика последовательно после вызова std::raise и последовательно перед возвратом из него выполняется в том же потоке, что и std::raise. Выполнение обработчиков для других сигналов является неупорядоченным по отношению к остальной части программы и выполняется в неуказанном потоке.

Два обращения к одному и тому же объекту типа volatile std::sig_atomic_t не приводят к гонке данных, если оба они происходят в одном и том же потоке, даже если один или несколько из них происходят в обработчике сигнала. Для каждого вызова обработчика сигнала оценки, выполняемые потоком, вызывающим обработчик сигнала, могут быть разделены на две группы A и B, так что никакие оценки в B не происходят до оценок в A, и оценки таких объектов volatile std::sig_atomic_t принимают значения, как если бы все вычисления в A произошли до выполнения обработчика сигнала и выполнение обработчика сигнала произошло до всех оценок в B.

(начиная с C++14)

[править] Примечание

POSIX требует, чтобы signal был потокобезопасным, и определяется список потокобезопасных асинхронных библиотечных функций, которые могут быть вызваны из любого обработчика сигнала.

Обработчики сигнала должны иметь связывание С, и, как правило, использовать только функции из общего подмножества C и C++. Возможность функции со связыванием C++ использоваться в качестве обработчика сигнала определяется реализацией.

(до C++17)

Нет никаких ограничений на связывание обработчиков сигналов.

(начиная с C++17)

[править] Пример

#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 << "Значение сигнала: " << gSignalStatus << '\n';
  std::cout << "Отправка сигнала: " << SIGINT << '\n';
  std::raise(SIGINT);
  std::cout << "Значение сигнала: " << gSignalStatus << '\n';
}

Возможный вывод:

Значение сигнала: 0
Отправка сигнала: 2
Значение сигнала: 2

[править] Ссылки

  • C++23 стандарт (ISO/IEC 14882:2023):
  • 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 для сигналов безопасен

[править] Смотрите также

выполняет обработчик для конкретного сигнала
(функция) [править]
барьер между потоком и обработчиком сигнала, выполняемым в этом же потоке
(функция) [править]