Buscar..
Sintaxis
- alarma sin firmar (segundos sin firmar);
- int kill (pid_t pid, int sig);
Parámetros
| Función, parámetro (s), valor de retorno | Descripción | 
|---|---|
| alarm() | nombre de la función | 
| unsigned seconds | Segundos para activar una alarma o 0 para cancelar cualquier alarma pendiente | 
| > = 0 | 0 si no hay ninguna otra alarma pendiente, de lo contrario, la cantidad de segundos que la alarma pendiente aún estaba abierta. Esta función no fallará. | 
| - | - | 
| kill() | nombre de la función | 
| pid_t pid | . | 
| int sig | 0 o ID de señal | 
| 0, -1 | En caso de éxito se devuelve 0, -1 en caso de error con la configuración de errnoenEINVAL,EPERMoESRCH. | 
Levantando SIGALARM con la acción por defecto.
 Usando la alarm , el usuario puede programar la señal SIGALARM para que se eleve después del intervalo especificado. En caso de que el usuario no haya bloqueado, ignorado o especificado el manejador de señales explícito para esta señal, la acción predeterminada para esta señal se realizará al llegar. Según la especificación, la acción predeterminada para SIGALARM es finalizar el proceso: 
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char** argv)
{
    printf("Hello!\n");
    // Set the alarm for five second
    alarm(5); // Per POSIX, this cannot fail
    // Now sleep for 15 seconds
    for (int i = 1; i <= 15; i++)
    {
        printf("%d\n", i);
        sleep(1);
    }
    // And print the message before successful exit
    printf("Goodbye!\n");
    return EXIT_SUCCESS;
}
Esto produce:
Hello!
1
2
3
4
5
[2]    35086 alarm      ./a.out
Configuración del manejador de señales usando sigaction y elevando señales usando raise
 Para que un programa reaccione a una determinada señal, además de usar una acción predeterminada, el controlador de señales personalizado se puede instalar utilizando sigaction . sigaction recibe tres argumentos: señal para actuar, puntero a la estructura sigaction_t que, si no es NULL , describe un nuevo comportamiento y puntero a sigaction_t que, si no es NULL , se rellenará con el comportamiento anterior (para que uno pueda restaurarlo). Las señales de aumento en el mismo proceso se pueden hacer con el método de raise . Si se necesita más control (para enviar la señal a algún otro proceso, se puede usar kill o pthread_kill , que aceptan el ID del proceso de destino o el ID del hilo). 
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Signals are numbered from 1, signal 0 doesn't exist
volatile sig_atomic_t last_received_signal = 0;
// Signal handler, will set the global variable
// to indicate what is the last signal received.
// There should be as less work as possible inside
// signal handler routine, and one must take care only
// to call reentrant functions (in case of signal arriving
// while program is already executing same function)
void signal_catcher(int signo, siginfo_t *info, void *context)
{
    last_received_signal = info->si_signo;
}
int main (int argc, char** argv)
{
    // Setup a signal handler for SIGUSR1 and SIGUSR2
    struct sigaction act;
    memset(&act, 0, sizeof act);
    // sigact structure holding old configuration
    // (will be filled by sigaction):
    struct sigaction old_1;
    memset(&old_1, 0, sizeof old_1);
    struct sigaction old_2;
    memset(&old_2, 0, sizeof old_2);
    act.sa_sigaction = signal_catcher;
    // When passing sa_sigaction, SA_SIGINFO flag
    // must be specified. Otherwise, function pointed
    // by act.sa_handler will be invoked
    act.sa_flags = SA_SIGINFO;
    if (0 != sigaction(SIGUSR1, &act, &old_1))
    {
        perror("sigaction () failed installing SIGUSR1 handler");
        return EXIT_FAILURE;
    }
    if (0 != sigaction(SIGUSR2, &act, &old_2))
    {
        perror("sigaction() failed installing SIGUSR2 handler");
        return EXIT_FAILURE;
    }
    // Main body of "work" during which two signals
    // will be raised, after 5 and 10 seconds, and which
    // will print last received signal
    for (int i = 1; i <= 15; i++)
    {
        if (i == 5)
        {
            if (0 != raise(SIGUSR1))
            {
                perror("Can't raise SIGUSR1");
                return EXIT_FAILURE;
            }
        }
        if (i == 10)
        {
            if (0 != raise(SIGUSR2))
            {
                perror("Can't raise SIGUSR2");
                return EXIT_FAILURE;
            }
        }
        printf("Tick #%d, last caught signal: %d\n",
            i, last_received_signal);
        sleep(1);
    }
    // Restore old signal handlers
    if (0 != sigaction(SIGUSR1, &old_1, NULL))
    {
        perror("sigaction() failed restoring SIGUSR1 handler");
        return EXIT_FAILURE;
    }
    if (0 != sigaction(SIGUSR2, &old_2, NULL))
    {
        perror("sigaction() failed restoring SIGUSR2 handler");
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}
Esto produce:
Tick #1, last caught signal: 0
Tick #2, last caught signal: 0
Tick #3, last caught signal: 0
Tick #4, last caught signal: 0
Tick #5, last caught signal: 30
Tick #6, last caught signal: 30
Tick #7, last caught signal: 30
Tick #8, last caught signal: 30
Tick #9, last caught signal: 30
Tick #10, last caught signal: 31
Tick #11, last caught signal: 31
Tick #12, last caught signal: 31
Tick #13, last caught signal: 31
Tick #14, last caught signal: 31
Tick #15, last caught signal: 31
Un proceso de suicidio usando kill ().
 Un proceso puede (intentar) enviar una señal a cualquier otro proceso utilizando la función kill() . 
 Para hacerlo, el proceso de envío debe conocer el PID del proceso de recepción. Como, sin introducir una carrera, un proceso solo puede estar seguro de su propio PID (y los PID de sus hijos) el ejemplo más simple para demostrar el uso de kill() es hacer que un proceso se envíe una señal a sí mismo. 
 Debajo de un ejemplo de un proceso que inicia su propia terminación enviándose una señal de interrupción ( SIGKILL ): 
#define _POSIX_C_SOURCE 1
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int main (void)
{
  pid_t pid = getpid(); /* Get my iown process ID. */
  kill(pid, SIGKILL); /* Send myself a KILL signal. */
  puts("Signal delivery initiated.");  /* Although not guaranteed, 
                                  practically the program never gets here. */
  pause(); /* Wait to die. */
  puts("This never gets printed.");
}
Salida:
Killed
(... o similar, dependiendo de la implementación)
Manejar SIGPIPE generado por write () de manera segura para subprocesos
 Cuando se llama a write() para una tubería o secuencia con nombre o sin nombre cuyo final de lectura está cerrado, suceden dos cosas: 
-  SIGPIPEseñalSIGPIPEse envía al proceso que llamówrite()
-  SIGPIPEseñalSIGPIPEse envía al hilo que llamówrite()
-  Error de EPIPEes devuelto porwrite()
 Hay varias maneras de tratar con SIGPIPE : 
-  Para sockets, SIGPIPEse puede deshabilitar configurando opciones específicas de la plataforma comoMSG_NOSIGNALen Linux ySO_NOSIGPIPEen BSD (funciona solo parasend, pero no parawrite). Esto no es portátil.
-  Para las FIFO (tuberías con nombre), no se generará SIGPIPEsi el escritor usaO_RDWRlugar deO_WRONLY, de modo que la lectura final siempre se abre. Sin embargo, esto desactivaEPIPEtambién.
-  Podemos ignorar SIGPIPEo establecer un controlador global. Esta es una buena solución, pero no es aceptable si no controla toda la aplicación (por ejemplo, está escribiendo una biblioteca).
-  Con las versiones recientes de POSIX, podemos usar el hecho de que SIGPIPEse envía al subproceso que se llamawrite()y manejarlo utilizando una técnica de manejo de señales síncronas.
 El código siguiente demuestra el manejo de SIGPIPE seguro para subprocesos para POSIX.1-2004 y posteriores. 
Está inspirado en este post :
-  Primero, agregue SIGPIPEpara señalar la máscara del hilo actual usandopthread_sigmask().
-  Compruebe si ya hay un SIGPIPEpendiente utilizandosigpending().
-  Llamar a write(). Si el final de la lectura está cerrado, se añadiráSIGPIPEa la máscara de señales pendientes y seEPIPE.
-  Si write()devolvióEPIPE, ySIGPIPEno estaba aún pendiente antes dewrite(), elimínelo de la máscara de señales pendientes mediantesigtimedwait().
-  Restaure la máscara de señal original usando pthread_sigmask().
Código fuente:
#include <unistd.h>
#include <time.h>
#include <errno.h>
#include <sys/signal.h>
ssize_t safe_write(int fd, const void* buf, size_t bufsz)
{
    sigset_t sig_block, sig_restore, sig_pending;
    sigemptyset(&sig_block);
    sigaddset(&sig_block, SIGPIPE);
    /* Block SIGPIPE for this thread.
     *
     * This works since kernel sends SIGPIPE to the thread that called write(),
     * not to the whole process.
     */
    if (pthread_sigmask(SIG_BLOCK, &sig_block, &sig_restore) != 0) {
        return -1;
    }
    /* Check if SIGPIPE is already pending.
     */
    int sigpipe_pending = -1;
    if (sigpending(&sig_pending) != -1) {
        sigpipe_pending = sigismember(&sig_pending, SIGPIPE);
    }
    if (sigpipe_pending == -1) {
        pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
        return -1;
    }
    ssize_t ret;
    while ((ret = write(fd, buf, bufsz)) == -1) {
        if (errno != EINTR)
            break;
    }
    /* Fetch generated SIGPIPE if write() failed with EPIPE.
     *
     * However, if SIGPIPE was already pending before calling write(), it was
     * also generated and blocked by caller, and caller may expect that it can
     * fetch it later. Since signals are not queued, we don't fetch it in this
     * case.
     */
    if (ret == -1 && errno == EPIPE && sigpipe_pending == 0) {
        struct timespec ts;
        ts.tv_sec = 0;
        ts.tv_nsec = 0;
        int sig;
        while ((sig = sigtimedwait(&sig_block, 0, &ts)) == -1) {
            if (errno != EINTR)
                break;
        }
    }
    pthread_sigmask(SIG_SETMASK, &sig_restore, NULL);
    return ret;
}