Enviar señal a un proceso en C

Jinku Hu 12 octubre 2023
  1. Utilice la función kill para enviar señal a un proceso en C
  2. Utilice la función kill y la señal nula para comprobar la existencia del proceso en C
Enviar señal a un proceso en C

Este artículo explicará varios métodos de cómo enviar una señal a un proceso en C.

Utilice la función kill para enviar señal a un proceso en C

Las señales son notificaciones de tipo interrupción que pueden indicar un evento específico y pueden enviarse a un proceso. Un proceso puede enviar una señal a otro si el primero tiene los permisos adecuados. Las señales son un tipo de comunicación entre procesos que se puede utilizar para interactuar con diferentes programas, con procesos secundarios o con subprocesos. La función kill se puede utilizar para enviar varias señales a un proceso. Se necesitan dos argumentos: un ID de proceso y un número de señal para entregar. Tenga en cuenta que los números de señal son enteros constantes que se definen como macros de tipo SIG___.

En el siguiente ejemplo, demostramos un programa que crea un proceso hijo con la llamada fork y luego ejecuta el bucle infinito incrementando un número entero. Mientras tanto, el proceso padre emite una señal SIGTERM, que finaliza el proceso hijo, y la función principal sale después de recibir el código de estado hijo mediante la llamada waitpid.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int wstatus;

  pid_t c_pid = fork();
  if (c_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (c_pid == 0) {
    printf("printed from child process - %d\n", getpid());

    int count = 0;

    while (1) {
      count += 1;
    }

    exit(EXIT_SUCCESS);
  } else {
    printf("printed from parent process - %d\n", getpid());
    int ret;

    ret = kill(c_pid, SIGTERM);
    if (ret == -1) {
      perror("kill");
      exit(EXIT_FAILURE);
    }

    if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
      perror("waitpid");
      exit(EXIT_FAILURE);
    }
  }

  exit(EXIT_SUCCESS);
}

Utilice la función kill y la señal nula para comprobar la existencia del proceso en C

Otro caso de uso de la función kill es comprobar la existencia del proceso. Incluso cuando intenta verificar la existencia de algún proceso con este método, puede haber un escenario en el que el estado recuperado sea incorrecto. Esto puede deberse a que el proceso observado ya ha finalizado y un programa diferente está utilizando el mismo ID, ya que el sistema operativo permite la reutilización de números de identificación.

kill necesita pasar un número de señal - cero, y el código de retorno de la función debe ser probado para códigos errno. Es decir, si kill devuelve el código de error -1 y errno se establece en ESRCH, el proceso dado no existe. Si el código de error se devuelve con el valor EPERM de errno, el programa existe, pero el proceso de la persona que llama no tiene permiso para enviar una señal. En caso de que se devuelva el cero, el proceso existe y el proceso de la persona que llama puede enviarle otras señales.

El siguiente ejemplo de código implementa las declaraciones de verificación de estado anteriores e imprime el mensaje correspondiente.

#include <errno.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>

int main(int argc, char *argv[]) {
  int wstatus;

  pid_t c_pid = fork();
  if (c_pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
  }

  if (c_pid == 0) {
    printf("printed from child process - %d\n", getpid());

    int count = 10;

    while (count >= 0) {
      count -= 1;
      sleep(1);
    }

    exit(EXIT_SUCCESS);
  } else {
    printf("printed from parent process - %d\n", getpid());
    int ret;

    errno = 0;
    ret = kill(c_pid, 0);
    if (ret == -1) {
      if (errno == EPERM)
        printf(
            "Process exists, but we don't have "
            "permission to send it a signal\n");
      else if (errno == ESRCH)
        printf("Process does not exist\n");
      else
        perror("kill");
      exit(EXIT_FAILURE);
    } else {
      printf("Process exists and we can send it a signal\n");
    }

    if (waitpid(c_pid, &wstatus, WUNTRACED | WCONTINUED) == -1) {
      perror("waitpid");
      exit(EXIT_FAILURE);
    }
  }

  exit(EXIT_SUCCESS);
}
Autor: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook

Artículo relacionado - C Signal