Я учусь связи между процессами в Linux, используя убить() для передачи сигналов на спящий ребенок process.Here моей программа:Почему мой обработчик сигнала выполняет дважды?
8 void func(void);
9 int main(void){
10 int i, j;
11 pid_t status, retpid;
12 signal(17,func);
13 if(i = fork()){
14 printf("Parent:signal 17 will be sent to child!\n");
15 kill(i, 17);
16 wait(0);
17 printf("child process terminated\n");
18 }
19 else{
20 sleep(10);
21 printf("Child: A signal from my parent is received!\n");
22 exit(0);
23 }
24 }
25 void func(void)
26 {
27 printf("the signal has been sent!\n");
28 }
Собран с НКОЙ, программа производства аномального результата, в котором функ () выполняется дважды:
./test4.out
Parent:signal 17 will be sent to child!
the signal has been sent!
Child: A signal from my parent is received!
the signal has been sent!
child process terminated
Я проанализировал результат, а затем удаляется следующие две строки:
16 wait(0);
17 printf("child process terminated\n");
и результат б ecame normal, с func(), вызываемым только один раз. Похоже, что виновником является функция wait(), но почему она когда-либо вызывала обработчик сигнала?
** Может быть **, когда родительский процесс закрывается, он ждет сигнала KILL из процесса-жнеца ...? После завершения процесса он не умирает. Он остается до тех пор, пока не будет завершен «обманщик» (либо владелец, либо системный процесс, отвечающий за получение процессов зомби). Это может быть сигнализация жнеца, что это сделано. – Myst
'printf' не является сигнальной функцией и не должен вызываться в обработчике сигнала. Возможное объяснение состоит в том, что он вызывает неопределенное поведение (например, дважды очищает буфер толстого хода - один раз в обработчике сигнала и один раз, когда процесс завершается). – kaylum
, пожалуйста, отправьте текстовый код, а не с добавленными номерами строк. Мы не можем просто захватить опубликованный код и вставить его в наши редакторы, не выполняя много строк за строкой. Не используйте вкладки для отступов, так как каждый текстовый редактор/редактор имеет ширину табуляции/ширину табуляции, заданную для индивидуальных предпочтений. Даже после исправления проблемы с номером строки, опубликованный код не компилируется. Кажется, что отсутствуют необходимые инструкции '# include' – user3629249