Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

195
Views
Ejemplo de controlador de señal en la interfaz de programación de Linux

El siguiente ejemplo de The Programming Linux Programming Interface de Michael Kerrisk

 static void sigHandler(int sig){ printf("Ouch!\n"); } int main(int argc, char *argv[]) { int j; if (signal(SIGINT, sigHandler) == SIG_ERR) errExit("signal"); for (j = 0; ; j++){ printf("%d\n", j); sleep(3); } }

se supone que imprime "¡Ay!" al terminal cada vez que el usuario pulsa Control-C (CTRL+C); en el propio ejemplo del autor, lo escribe dos veces antes de salir finalmente de la terminal con Control-\ (CTRL+\ ).

Cuando hago esto, el programa funciona como se esperaba solo en la primera ejecución de CTRL+C. Si lo escribo por segunda vez, como lo hace el autor en su ejemplo, mi programa cierra la terminal, no imprime "¡Ay!" ni continúa ejecutándose (en bucle).

Utilicé exactamente el mismo código que se proporciona aquí, en el sitio web del libro:

Ay.c

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Por lo general, la signal necesita que se vuelva a instalar el controlador de señal. De lo contrario, por defecto es SIG_DFL (acción por defecto correspondiente a la señal). La acción predeterminada para SIGINT es terminar el programa.

Tenga en cuenta que printf(3) no es una de las funciones asíncronas seguras. Entonces podría escribir (2) para hacer lo mismo. Consulte la lista POSIX de funciones seguras para señales asíncronas.

Reinstalarlo debería funcionar como se esperaba:

 static void sigHandler(int sig){ signal(SIGINT, sigHandler); write(STDOUT_FILENO, "Ouch!\n", 6); }

Esta es una de las razones por las que debe evitar signal y usar sigaction en su lugar. El comportamiento mencionado anteriormente no es universal en todas las plataformas. Entonces, tal vez, la plataforma que está ejecutando no es en la que el autor probó su código o está usando un kernel de Linux diferente.

El comportamiento en el que necesita volver a instalar el controlador de señal al recibir una señal es el comportamiento del Sistema V. Pero la semántica BSD no necesita reinstalación. Hasta hace poco, Linux mostraba el comportamiento de System V, pero parece haberse solucionado en el kernel reciente y no veo esto en mi kernel 3.19, pero puedo ver el kernel 2.6.32 (considerablemente antiguo).

La documentación de Signal dice:

 The situation on Linux is as follows: * The kernel's signal() system call provides System V semantics. * By default, in glibc 2 and later, the signal() wrapper function does not invoke the kernel system call. Instead, it calls sigaction(2) using flags that supply BSD semantics. This default behavior is provided as long as the _BSD_SOURCE feature test macro is defined. By default, _BSD_SOURCE is defined; it is also implicitly defined if one defines _GNU_SOURCE, and can of course be explicitly defined. * On glibc 2 and later, if the _BSD_SOURCE feature test macro is not defined, then signal() provides System V semantics. (The default implicit definition of _BSD_SOURCE is not provided if one invokes gcc(1) in one of its standard modes (-std=xxx or -ansi) or defines various other feature test macros such as _POSIX_SOURCE, _XOPEN_SOURCE, or _SVID_SOURCE; see feature_test_macros(7).)

Por lo tanto, podría trabajar definiendo _BSD_SOURCE para obtener la semántica BSD. Por lo tanto, el comportamiento que observa es más probable porque la signal en su sistema sigue la semántica de System V y Linux reciente (y probablemente en lo que Kerrisk lo probó) sigue la semántica de BSD.

over 4 years ago · Santiago Trujillo Report

0

no debe usar printf() en los controladores de señales y excepciones porque no son reentrantes. printf también almacena datos en la memoria antes de poner esto en la consola, por lo que usar fflush() ayudará a imprimir, pero no se recomienda. para fines de prueba, use el contador (bandera) en el controlador y use el controlador externo printf. no use la señal () para registrar el controlador ya que cada versión de Unix (BSD, Linux) no proporciona la misma implementación. En su lugar, utilice sigaction.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!