std:: signal
|
Definido en el encabezado
<csignal>
|
||
|
/* signal-handler */
*
signal
(
int
sig,
/* signal-handler */
*
handler
)
;
|
(1) | |
|
extern
"C"
using
/* signal-handler */
=
void
(
int
)
;
|
(2) | ( solo para exposición* ) |
Cambia el manejo de la señal sig . Dependiendo de handler , la señal puede ser ignorada, establecida a valores predeterminados o manejada por una función definida por el usuario.
Cuando el manejador de señales se establece a una función y ocurre una señal, está definido por la implementación si std :: signal ( sig, SIG_DFL ) se ejecutará inmediatamente antes del inicio del manejador de señales. Además, la implementación puede prevenir que ocurra algún conjunto de señales definido por la implementación mientras se ejecuta el manejador de señales.
Para algunas de las señales, la implementación puede llamar std :: signal ( sig, SIG_IGN ) al inicio del programa. Para el resto, la implementación debe llamar std :: signal ( sig, SIG_DFL ) .
(Nota: POSIX introdujo
sigaction
para estandarizar estos comportamientos definidos por la implementación)
Contenidos |
Parámetros
| sig | - |
la señal para establecer el manejador de señales. Puede ser un valor definido por la implementación o uno de los siguientes valores:
|
||||||
| handler | - |
el manejador de señales. Debe ser uno de los siguientes:
|
Valor de retorno
Manejador de señal anterior en caso de éxito o SIG_ERR en caso de fallo (establecer un manejador de señales puede estar deshabilitado en algunas implementaciones).
Manejador de señales
Las siguientes limitaciones se imponen a la función definida por el usuario que se instala como un manejador de señales.
|
Si el manejador de señales es llamado NO como resultado de std::abort o std::raise (señal asíncrona), el comportamiento es indefinido si
|
(hasta C++17) |
|
Una operación atómica simple sin bloqueo es una invocación de una función f desde <atomic> o <stdatomic.h> (desde C++23) , tal que:
El comportamiento es indefinido si cualquier manejador de señales realiza cualquiera de las siguientes acciones:
|
(desde C++17) |
Si la función definida por el usuario retorna al manejar SIGFPE , SIGILL , SIGSEGV o cualquier otra señal definida por la implementación que especifique una excepción computacional, el comportamiento es indefinido.
Si el manejador de señales es llamado como resultado de std::abort o std::raise (señal síncrona), el comportamiento es indefinido si el manejador de señales llama a std::raise .
|
Al entrar al manejador de señales, el estado del entorno de punto flotante y los valores de todos los objetos no están especificados, excepto para
Al retornar de un manejador de señales, el valor de cualquier objeto modificado por el manejador de señales que no sea volatile std:: sig_atomic_t o atómico sin bloqueo std::atomic es indeterminado. |
(hasta C++14) | ||
|
Una llamada a la función
Si un manejador de señales se ejecuta como resultado de una llamada a
std::raise
(sincrónicamente), entonces la ejecución del manejador está
secuenciada después
de la invocación de
Dos accesos al mismo objeto de tipo volatile std:: sig_atomic_t no resultan en una carrera de datos si ambos ocurren en el mismo hilo, incluso si uno o más ocurren en un manejador de señales. Para cada invocación del manejador de señales, las evaluaciones realizadas por el hilo que invoca un manejador de señales pueden dividirse en dos grupos A y B, de modo que ninguna evaluación en B ocurre antes de las evaluaciones en A, y las evaluaciones de dichos volatile std:: sig_atomic_t toman valores como si todas las evaluaciones en A ocurrieran antes de la ejecución del manejador de señales y la ejecución del manejador de señales ocurriera antes de todas las evaluaciones en B. |
(desde C++14) |
Notas
POSIX requiere que
signal
sea seguro para hilos, y
especifica una lista de funciones de biblioteca async-signal-safe
que pueden ser llamadas desde cualquier manejador de señales.
Se espera que los manejadores de señales tengan vinculación C y, en general, solo utilicen las características del subconjunto común de C y C++. Sin embargo, las implementaciones comunes permiten utilizar una función con vinculación C++ como manejador de señales.
Ejemplo
#include <csignal> #include <iostream> namespace { volatile std::sig_atomic_t gSignalStatus; } void signal_handler(int signal) { gSignalStatus = signal; } int main() { // Instalar un manejador de señales std::signal(SIGINT, signal_handler); std::cout << "SignalValue: " << gSignalStatus << '\n'; std::cout << "Sending signal: " << SIGINT << '\n'; std::raise(SIGINT); std::cout << "SignalValue: " << gSignalStatus << '\n'; }
Salida posible:
SignalValue: 0 Sending signal: 2 SignalValue: 2
Referencias
- Estándar C++23 (ISO/IEC 14882:2024):
-
- 17.13.5 Manejadores de señales [support.signal]
- Estándar C++20 (ISO/IEC 14882:2020):
-
- 17.13.5 Manejadores de señales [support.signal]
- Estándar C++17 (ISO/IEC 14882:2017):
-
- 21.10.4 Manejadores de señal [support.signal]
Informes de defectos
Los siguientes informes de defectos que modifican el comportamiento se aplicaron retroactivamente a los estándares publicados anteriormente de C++.
| DR | Aplicado a | Comportamiento publicado | Comportamiento correcto |
|---|---|---|---|
| LWG 3756 | C++17 | no estaba claro si std::atomic_flag es seguro para señales | lo es |
Véase también
|
ejecuta el manejador de señal para una señal particular
(función) |
|
|
(C++11)
|
barrera entre un hilo y un manejador de señal ejecutado en el mismo hilo
(función) |
|
Documentación C
para
signal
|
|