#c #unix #signals #kill
#c #unix #сигналы #уничтожить
Вопрос:
Я пытаюсь использовать этот пример, который я взял из:http://www.cs.cf.ac.uk/Dave/C/node24.html:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void sighup(); /* routines child will call upon sigtrap */
void sigint();
void sigquit();
main() {
int pid;
/* get child process */
if ((pid = fork()) < 0) {
perror("fork");
exit(1);
}
if (pid == 0) { /* child */
printf("nI am the new child!nn");
signal(SIGHUP,sighup); /* set function calls */
signal(SIGINT,sigint);
signal(SIGQUIT, sigquit);
printf("nChild going to loop...nn");
for(;;); /* loop for ever */
}
else /* parent */
{ /* pid hold id of child */
printf("nPARENT: sending SIGHUPnn");
kill(pid,SIGHUP);
sleep(3); /* pause for 3 secs */
printf("nPARENT: sending SIGINTnn");
kill(pid,SIGINT);
sleep(3); /* pause for 3 secs */
printf("nPARENT: sending SIGQUITnn");
kill(pid,SIGQUIT);
sleep(3);
}
}
void sighup() {
signal(SIGHUP,sighup); /* reset signal */
printf("CHILD: I have received a SIGHUPn");
}
void sigint() {
signal(SIGINT,sigint); /* reset signal */
printf("CHILD: I have received a SIGINTn");
}
void sigquit() {
printf("My DADDY has Killed me!!!n");
exit(0);
}
Но я не вижу никаких выходных данных от дочернего процесса.
Это ожидаемое поведение? Если да, то почему?
Большое вам спасибо!
Ответ №1:
В вашем коде есть серьезное условие гонки. Вы не гарантируете, что дочерний сервер завершил вызов signal
до того, как родительский сервер отправит сигналы. Вам либо нужно использовать какой-то примитив синхронизации, чтобы заставить родительский элемент ждать, пока дочерний элемент установит обработчики, либо вам нужно установить обработчики сигналов перед разветвлением, чтобы дочерний элемент унаследовал их.
Вот самый простой я знаю способ синхронизации процессов, подобных этому:
- Перед разветвлением вызовите
pipe(p)
для создания канала. fork()
.- В родительском,
close(p[1]);
(конец записи) иread(p[0], amp;dummy, 1);
- В дочернем,
close(p[0]);
иclose(p[1]);
после установки обработчиков сигналов. - Когда родительский сервер возвращается из
read
, вы можете быть уверены, что дочерний сервер настроил свои обработчики сигналов. На этом этапе вы также можетеclose(p[0]);
использовать родительский файл.
Правка 2: Возможно, лучший и более простой подход:
- Перед разветвлением вызовите
sigprocmask
, чтобы заблокировать все сигналы и сохранить старую маску сигнала. - В родительском файле вызовите
sigprocmask
снова сразу после разветвления, чтобы восстановить исходную маску сигнала. - В дочернем элементе вызовите
sigprocmask
сразу после установки обработчиков сигналов, чтобы восстановить исходную маску сигнала.
Ответ №2:
Вы должны использовать getpid() вместо pid().
Комментарии:
1. OP, упомянутый вывод из дочернего процесса () отсутствует. getpid() выдаст только идентификатор процесса. решит ли это проблему?