Signal an einen Prozess senden in C

Jinku Hu 12 Oktober 2023
  1. Verwenden Sie die Funktion kill, um ein Signal an einen Prozess in C zu senden
  2. Verwenden Sie die Funktion kill und das Nullsignal, um die Existenz des Prozesses in C zu überprüfen
Signal an einen Prozess senden in C

In diesem Artikel werden verschiedene Methoden zum Senden eines Signals an einen Prozess in C erläutert.

Verwenden Sie die Funktion kill, um ein Signal an einen Prozess in C zu senden

Signale sind Benachrichtigungen im Interrupt-Stil, die das bestimmte Ereignis kennzeichnen und an einen Prozess gesendet werden können. Ein Prozess kann ein Signal an einen anderen senden, wenn der erste die richtigen Berechtigungen hat. Signale sind eine Art prozessübergreifende Kommunikation, die zur Interaktion mit verschiedenen Programmen, untergeordneten Prozessen oder Threads verwendet werden kann. Mit der Funktion kill können verschiedene Signale an einen Prozess gesendet werden. Es werden zwei Argumente benötigt - eine Prozess-ID und eine zu liefernde Signalnummer. Beachten Sie, dass Signalnummern konstante Ganzzahlen sind, die als Makros vom Typ SIG___ definiert sind.

Im folgenden Beispiel zeigen wir ein Programm, das mit dem Aufruf fork einen untergeordneten Prozess erstellt und dann die Endlosschleife ausführt, die eine Ganzzahl inkrementiert. Währenddessen gibt der übergeordnete Prozess ein SIGTERM-Signal aus, das den untergeordneten Prozess beendet, und die Hauptfunktion wird beendet, nachdem der untergeordnete Statuscode mit dem Aufruf waitpid empfangen wurde.

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

Verwenden Sie die Funktion kill und das Nullsignal, um die Existenz des Prozesses in C zu überprüfen

Ein weiterer Anwendungsfall für die Funktion kill besteht darin, die Existenz des Prozesses zu überprüfen. Selbst wenn Sie versuchen, mit dieser Methode das Vorhandensein eines Prozesses zu überprüfen, kann es vorkommen, dass der abgerufene Status falsch ist. Dies kann verursacht werden, wenn der beobachtete Prozess bereits beendet ist und ein anderes Programm dieselbe ID verwendet, da das Betriebssystem die Wiederverwendung von Identifikationsnummern zulässt.

kill muss eine Signalnummer - Null übergeben werden, und der Rückkehrcode der Funktion sollte auf errno-Codes getestet werden. Wenn nämlich kill den Fehlercode -1 zurückgibt und errno auf ESRCH gesetzt ist, existiert der angegebene Prozess nicht. Wenn der Fehlercode mit dem Wert EPERM von errno zurückgegeben wird, ist das Programm vorhanden, aber der Aufruferprozess hat nicht die Berechtigung, ein Signal zu senden. Wenn die Null zurückgegeben wird, existiert der Prozess und der Anruferprozess kann ihm andere Signale senden.

Das folgende Codebeispiel implementiert die obigen Anweisungen zur Statusprüfung und druckt die entsprechende Nachricht.

#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

Verwandter Artikel - C Signal