#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 где-нибудь.