Invia segnale a un processo in C
-
Usa la funzione
kill
per inviare il segnale a un processo in C -
Usa la funzione
kill
e il segnale nullo per verificare l’esistenza del 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);
}
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