Invia segnale a un processo in C

Jinku Hu 12 ottobre 2023
  1. Usa la funzione kill per inviare il segnale a un processo in C
  2. Usa la funzione kill e il segnale nullo per verificare l’esistenza del processo in C
Invia segnale a un processo in C

Questo articolo spiegherà diversi metodi su come inviare un segnale a un processo in C.

Usa la funzione kill per inviare il segnale a un processo in C

I segnali sono notifiche in stile interrupt che possono denotare l’evento specifico e possono essere inviate a un processo. Un processo può inviare un segnale a un altro se il primo ha le autorizzazioni corrette. I segnali sono un tipo di comunicazione tra processi che può essere utilizzato per interagire con diversi programmi, con processi figlio o con thread. La funzione kill può essere utilizzata per inviare vari segnali a un processo. Sono necessari due argomenti: un ID processo e un numero di segnale da fornire. Notare che i numeri di segnale sono numeri interi costanti definiti come macro di tipo SIG___.

Nell’esempio seguente, mostriamo un programma che crea un processo figlio con la chiamata fork e quindi esegue il bucle infinito incrementando un numero intero. Nel frattempo, il processo genitore emette un segnale SIGTERM, che termina il processo figlio, e la funzione main esce dopo aver ricevuto il codice di stato figlio usando la chiamata 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);
}

Usa la funzione kill e il segnale nullo per verificare l’esistenza del processo in C

Un altro caso d’uso per la funzione kill è verificare l’esistenza del processo. Anche quando si tenta di verificare l’esistenza di un processo con questo metodo, potrebbe esserci uno scenario in cui lo stato recuperato non è corretto. Ciò può essere causato quando il processo osservato è già terminato e un programma diverso utilizza lo stesso ID poiché il sistema operativo consente il riutilizzo dei numeri di identificazione.

A kill deve essere passato un numero di segnale - zero, e il codice di ritorno della funzione dovrebbe essere testato per i codici errno. Vale a dire, se kill restituisce il codice di errore -1 e errno è impostato su ESRCH, il processo dato non esiste. Se il codice di errore viene restituito con il valore EPERM di errno - il programma esiste, ma il processo chiamante non ha il permesso di inviare un segnale. Nel caso in cui venga restituito lo zero, il processo esiste e il processo chiamante può inviargli altri segnali.

Il seguente codice di esempio implementa le istruzioni di controllo dello stato precedenti e stampa il messaggio corrispondente.

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

Articolo correlato - C Signal