Enviar sinal para um processo em C

Jinku Hu 12 outubro 2023
  1. Use a função kill para enviar sinal para um processo em C
  2. Use a função kill e o sinal nulo para verificar a existência do processo em C
Enviar sinal para um processo em C

Este artigo irá explicar vários métodos de como enviar um sinal para um processo em C.

Use a função kill para enviar sinal para um processo em C

Os sinais são notificações de interrupção que podem denotar o evento específico e podem ser enviados para um processo. Um processo pode enviar um sinal para outro se o primeiro tiver as permissões corretas. Os sinais são um tipo de comunicação entre processos que podem ser utilizados para interagir com diferentes programas, com processos filhos ou com threads. A função kill pode ser usada para enviar vários sinais para um processo. São necessários dois argumentos - um ID de processo e um número de sinal a ser entregue. Observe que os números dos sinais são inteiros constantes que são definidos como macros do tipo SIG___.

No exemplo a seguir, demonstramos um programa que cria um processo filho com a chamada fork e, em seguida, executa o loop infinito incrementando um inteiro. Enquanto isso, o processo pai emite um sinal SIGTERM, que termina o processo filho e a função principal sai após receber o código de status filho usando a chamada 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);
}

Use a função kill e o sinal nulo para verificar a existência do processo em C

Outro caso de uso para a função kill é verificar a existência do processo. Mesmo quando você tenta verificar a existência de algum processo com esse método, pode haver um cenário em que o status recuperado esteja incorreto. Isso pode ser causado quando o processo observado já foi encerrado e um programa diferente está usando o mesmo ID, pois o sistema operacional permite a reutilização dos números de identificação.

kill precisa receber um número de sinal - zero, e o código de retorno da função deve ser testado para códigos errno. Ou seja, se kill retorna o código de erro -1 e errno é definido como ESRCH, o processo fornecido não existe. Se o código de erro for retornado com o valor EPERM de errno - o programa existe, mas o processo do chamador não tem permissão para enviar um sinal. Caso o zero seja retornado, o processo existe, e o processo do chamador pode enviar outros sinais para ele.

O exemplo de código a seguir implementa as instruções de verificação de status acima e imprime a mensagem correspondente.

#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

Artigo relacionado - C Signal