Espacios de nombres
Variantes
Acciones

std::signal

De cppreference.com
< cpp‎ | utility‎ | program
 
 
Biblioteca de servicios
 
Servicios de apoyo de programa
Terminación del programa
(C++11)
(C++11)
Comunicación con el entorno
Señales
Tipos de señales
Saltos no locales
Tipos
 
Definido en el archivo de encabezado <csignal>
/*controlador-de-señales*/* signal(int sig, /*controlador-de-señales*/* handler);
(1)
extern "C" using /*controlador-de-señales*/ = void(int); // solo exposición
(2)

Establece el controlador para la señal sig. El controlador de señales puede establecerse para que ocurra el control por defecto, la señal se ignore, o se llame a una función definida por el usuario.

Cuando un controlador de señales se establece a una función y una señal ocurre, está definido por la implementación si se ejecutará a std::signal(sig, SIG_DFL) inmediatamente antes del inicio del controlador de señales. La implementación también puede prevenir que ocurran algún conjunto de señales definidas por la implementación mientras ejecuta el controlador de señales.

Para algunas de las señales, la implementación puede llamar a std::signal(sig, SIG_IGN) al inicio del programa. Para el resto, la implementación deberá llamar a std::signal(sig, SIG_DFL).

(Nota: POSIX introdujo sigaction para estandarizar estos comportamientos definidos por la implementación)

Contenido

[editar] Parámetros

sig - La señal a la cual establecer el controlador de señales. Puede ser un valor definido por la implementación o uno de los siguientes valores:
Define los tipos de señales.
(constante de macro) [editar]


handler - El controlador de señales. Este debe ser uno se los siguientes:
  • La macro SIG_DFL. El controlador de señales se establece al controlador de señales por defecto.
  • La macro SIG_IGN . La señal se ignora.
  • Puntero a función. La signatura de la función debe ser equivalente a lo siguiente:
extern "C" void fun(int sig);

[editar] Valor de retorno

Si se tiene éxito, el controlador de señales previo, o SIG_ERR si hay un error (establecer un controlador de señales puede estar deshabilitado en algunas implementaciones).

[editar] Controlador de señales

Se imponen las siguientes limitaciones en la función definida por el usuario que se instala como un controlador de señales.

Si el controlador de señales se llama NO como resultado de std::abort o de std::raise (señal asíncrona), el comportamiento está indefinido si

  • el controlador de señales llama a cualquier función dentro de la biblioteca estándar, excepto a
  • std::abort
  • std::_Exit
  • std::quick_exit
  • std::signal con el primer argumento siendo el número de la señal actualmente controlada (un controlador asíncrono puede volver a registrarse por sí mismo, pero no otras señales).
  • el controlador de señales se refiere a cualquier objeto con duración de almacenamiento estática que no es std::atomic(desde C++11) o volatile std::sig_atomic_t.
(hasta C++17)

El comportamiento está indefinido si cualquier controlador de señales realiza cualquiera de los siguientes:

  • una llamada a cualquier función de la biblioteca, excepto las siguientes funciones seguras contra señales (observa que, en particular, la asignación de memoria dinámica no es segura contra señales):
  • acceso a un objeto con duración de almacenamiento local al hilo
  • una expresión dynamic_cast
  • una expresión throw
  • entrada a un bloque try, incluyendo un bloque try de función
  • inicialización de una variable estática que realiza inicialización dinámica no local (incluyendo aplazada hasta el primer uso ODR)
  • espera a que se complete la inicialización de cualquier variable con duración de almacenamiento estática debido a que otro hilo está inicializándola concurrentemente
(desde C++17)

Si la función definida por el usuario retorna al manejar a SIGFPE, SIGILL, SIGSEGV o a cualquier otra señal definida por la implementación que especifica una excepción computacional, el comportamiento está indefinido.

Si el controlador de señales se llama como resultado de std::abort o std::raise (señal síncrona), el comportamiento está indefinido si el controlador de señales llama a std::raise.

En la entrada al controlador de señales, el estado del entorno de punto flotante y los valores de todos los objetos está sin especificar, excepto por

Al retornar de un controlador de señales, el valor de cualquier objeto modificado por el controlador de señales que no sea volatile std::sig_atomic_t o std::atomic libre de bloqueo es indeterminado.

(hasta C++14)

Una llamada a la función signal() se sincroniza-con cualquier invocación resultante del controlador de señales.

Si un controlador de señales se ejecuta como resultado de una llamada a std::raise (de manera síncrona), entonces la ejecución del controlador está secuenciada-después de la invocación de std::raise y secuenciada-antes del retorno de ella y se ejecuta en el mismo hilo que std::raise. La ejecución de los controladores de otras señales está sin secuenciar con respecto al resto del programa y se ejecuta en un hilo inespecífico.

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, aun si uno o más ocurren en un controlador de señales. Para cada invocación del controlador de señales, las evaluaciones realizadas por el hilo que invoca a un controlador de señales pueden dividirse en dos grupos A and B, tal que ninguna evaluación en B sucede-antes que las evaluaciones en A, y las evaluaciones de tales objetos volatile std::sig_atomic_t toman valores como si todas las evaluaciones en A sucedieron-antes que la ejecución del controlador de señales y la ejecución del controlador de señales sucedió-antes que todas las evaluaciones en B.

(desde C++14)

[editar] Notas

POSIX requiere que signal sea segura contra hilos, y [http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_04 especifica una lista de funciones de biblioteca asíncronas seguras contra que pueden llamarse desde cualquier controlador de señales.

Se espera que los controladores de señales tengan enlace C y, en general, solamente utilicen las características del subconjunto común de C y C++. Está definido por la implementación si una función con enlace C++ puede usarse como un controlador de señales.

[editar] Ejemplo

#include <csignal>
#include <iostream>
 
namespace
{
  volatile std::sig_atomic_t gSignalStatus;
}
 
void signal_handler(int signal)
{
  gSignalStatus = signal;
}
 
int main()
{
  // Instalar un controlador de señales
  std::signal(SIGINT, signal_handler);
 
  std::cout << "SignalValue: " << gSignalStatus << '\n';
  std::cout << "Mandando signal " << SIGINT << '\n';
  std::raise(SIGINT);
  std::cout << "SignalValue: " << gSignalStatus << '\n';
}

Posible salida:

SignalValue: 0
Mandando signal 2
SignalValue: 2

[editar] Véase también

Ejecuta el controlador de señales para una señal en particular.
(función) [editar]
Barrera entre un hilo y un controlador de señales ejecutados en el mismo hilo/subproceso.
(función) [editar]