Envoyer un signal à un processus en C

Jinku Hu 12 octobre 2023
  1. Utilisez la fonction kill pour envoyer un signal à un processus en C
  2. Utilisez la fonction kill et le signal nul pour vérifier l’existence du processus en C
Envoyer un signal à un processus en C

Cet article explique plusieurs méthodes pour envoyer un signal à un processus en C.

Utilisez la fonction kill pour envoyer un signal à un processus en C

Les signaux sont des notifications de type interruption qui peuvent désigner l’événement spécifique et peuvent être envoyées à un processus. Un processus peut envoyer un signal à un autre si le premier a les bonnes autorisations. Les signaux sont un type de communication inter-processus qui peut être utilisé pour interagir avec différents programmes, avec des processus enfants ou avec des threads. La fonction kill permet d’envoyer différents signaux à un processus. Il faut deux arguments - un ID de processus et un numéro de signal à délivrer. Notez que les nombres de signaux sont des entiers constants définis comme des macros de type SIG___.

Dans l’exemple suivant, nous montrons un programme qui crée un processus enfant avec l’appel fork puis exécute la boucle infinie incrémentant un entier. Pendant ce temps, le processus parent émet un signal SIGTERM, qui termine le processus fils, et la fonction principale se termine après avoir reçu le code d’état enfant à l’aide de l’appel 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);
}

Utilisez la fonction kill et le signal nul pour vérifier l’existence du processus en C

Un autre cas d’utilisation de la fonction kill est de vérifier l’existence du processus. Même lorsque vous essayez de vérifier l’existence de certains processus avec cette méthode, il peut y avoir un scénario lorsque l’état récupéré est incorrect. Cela peut se produire lorsque le processus observé est déjà terminé et qu’un programme différent utilise le même ID puisque le système d’exploitation permet la réutilisation des numéros d’identification.

kill doit recevoir un numéro de signal - zéro, et le code de retour de la fonction doit être testé pour les codes errno. À savoir, si kill renvoie le code d’erreur -1 et que errno est défini sur ESRCH, le processus donné n’existe pas. Si le code d’erreur est retourné avec la valeur EPERM de errno - le programme existe, mais le processus appelant n’a pas l’autorisation d’envoyer un signal. Dans le cas où le zéro est renvoyé, le processus existe et le processus appelant peut lui envoyer d’autres signaux.

L’exemple de code suivant implémente les instructions de vérification d’état ci-dessus et imprime le message correspondant.

#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);
}
Auteur: 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

Article connexe - C Signal