Родительский процесс все еще получает сигнал, будучи приостановленным - PullRequest
0 голосов
/ 09 июня 2019

Я изучаю процессы в программировании Linux, есть этот код, который я не могу понять.Насколько я знаю, когда процесс приостановлен, он не получает сигналы (кроме того, который его разбудил), но в этом коде, когда родительский процесс выполняется, он вызывает wait, но он все еще выводит счетчик,что означает, что он получил SIGUSR1.Кто-нибудь может объяснить это?

Я уже знаю, что порядок или запуск произвольный, если дочерний процесс запускается первым, то проблем нет, но что, если родительский процесс запускается первым?

#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <unistd.h>
pid_t pid;
int counter = 0;
int status;
void handler1(int sig){counter ++;
  printf("counter = %d\n", counter);
  fflush(stdout);
  kill(pid, SIGUSR1);
}void handler2(int sig){counter += 3;
  printf("counter = %d\n", counter);
  exit(0);
}
int main() {
  signal(SIGUSR1, handler1);
  if ((pid = fork()) != 0) {
    pid_t p;
    if ((p = wait(&status)) > 0) {
      counter += 2;
      printf("counter = %d\n", counter);
    }
  } else {
    signal(SIGUSR1, handler2);
    kill(getppid(), SIGUSR1);
    while(1) {};
  }
}

Я ожидаю, что программа будет приостановлена, но каждый раз будет работать хорошо.

1 Ответ

0 голосов
/ 09 июня 2019

Процессы всегда получают сигналы, если не игнорируют их (signal(SIGnum, SIG_IGN);).

Неопределенные сигналы можно отложить, установив маску сигналов (например, с помощью sigprocmask, после их снятия маски вы получите ожидающие сигналы) или они будут отложены, если процесс остановлен (с помощью SIGSTOP / SIGTSTOP; отправка SIGCONT в процессы приводит к доставке ожидающих сигналов). (Обратите внимание, что сигналы не в реальном времени могут объединяться. Например, вы можете получить сигнал только один раз, когда он был отправлен 3 раза.)

Блокирует вызовы, такие как wait, блокирует / приостанавливает процесс до тех пор, пока он не завершится или пока доставка сигнала не прервет их.

Маскирование сигнала (например, с помощью sigprocmask) иногда называется блокировкой сигнала (от доставки), но это отличается от системного вызова блокировки, который блокирует / спит / приостанавливает процесс (блокирует его запуск на ЦП) .

...