SIGALRM не завершает программу по истечении указанного времени

#c #linux #process #signals

#c #linux #процесс #сигналы

Вопрос:

Я написал код на C, цель которого состоит в том, чтобы принять N в качестве входных данных, а затем создать N процессов и создать несколько собственных дочерних процессов. Каждый процесс отправляет сигналы от i 1-го процесса i 12-му процессу (не имеет значения, существует он или нет) сигнал SIGUSR1. Если процесс не получает никакого сигнала от какого-либо процесса, вы завершаете процесс. Идея состоит в том, чтобы закрыть весь процесс через 10 секунд с помощью SIGALRM, но программа не завершается. Если a принимает N в качестве входных данных через командную строку, программа работает, но если принимать через scanf, она каким-то образом ломается. TIA

 static int signal_receive = 0;

void sighandler(int signum){       //////////signal handler for SIGUSR1 signal
  signal_receive  ;
}

int main(void){

  int n;
  printf("enter N - ");
  scanf("%d", amp;n);

  int id1 = 1, id2 = 1;    //////// ids for tracking the process
  for(int i = 0; i<n;   i){
    if(id1>0 amp;amp; id2>0){     /////// only the grandparent can enter
      id1 = fork();
      int z = getpid()%13;
      for(int j = 0; j<z;   j){
        if(id2>0 amp;amp; id1==0)          //////// only the parent can enter
          id2 = fork();
      }
    }
  }

  alarm(10);          ///////// alarm for 10 seconds after which process stops sending SIGUSR1 and exits

  while(1){                       /////// SIGUSR1 signal
    sleep(2);
    for(int i = 1; i<13;   i)
      kill(getpid() i, SIGUSR1);
      if(signal_receive==0){
         printf("signal exited %dn", getpid());
      exit(0);
    }
  }

  for(int i = 0; i<n*13;   i)
    wait(NULL);

}

 

Комментарии:

1. Определенные проблемы: 1. fork() возвращает pid_t , не int . 2. Вам нужно добавить #include <unistd.h> , чтобы использовать fork() 3. Вы никогда не устанавливаете обработчик сигнала с signal() or even better помощью sigaction()` 4. static int signal_receive = 0; [должно быть volatile sig_atomic_t 5. getpid() i вообще не имеет смысла

2. отправленный не может проверять (и обрабатывать) ошибки с момента fork() сбоя вызова. Примечание: пользовательскому процессу разрешено создавать только (очень ограниченное) количество дочерних элементов

3. относительно: void sighandler(int signum){ //////////signal handler for SIGUSR1 signal signal_receive ; } параметр не обрабатывается. Это приведет к появлению сообщения от компилятора о «неиспользуемом параметре». Это не единственная проблема «не компилируется чисто» в коде.

4. опубликованный код не компилируется. в нем отсутствуют необходимые #include инструкции

Ответ №1:

 getpid() i
 

откуда вы знаете, что у i-го дочернего элемента есть этот pid? Это неверное предположение. Вы должны сохранить pid в таблице и использовать ее для завершения соответствующих процессов. Что-то вроде:

 pid_t pids[...];
int n;

...
id = fork();
if (id!=0) pids[n  ] = id; // store the new pid in the array
...


...
for (int i=0; i<n; i  )
   kill(pids[i],SIGUSR1); // get pids from array and kill them
...
 

Комментарии:

1. извините за неясность вопроса. Каждый процесс отправляет сигнал i 1-му процессу i 12-му процессу (не имеет значения, существует он или нет) сигнал SIGUSR1. Если процесс не получает никакого сигнала от какого-либо процесса, вы завершаете процесс. Я внес некоторые изменения в код. Пожалуйста, взгляните на это.

2. @ getpid() i johnny_bravo ничего не значит! Когда вы разветвляете, новый pid возвращается вызывающему, предоставляя вам pid дочернего элемента, но pid дочернего элемента не имеет ничего общего с pid отца, для i-го дочернего элемента нет отношения caller_pid i! Не делай этого. Как я уже сказал, сначала храните pid где-нибудь.