Когда функция wait() (в LINUX) реагирует на прерывания?
У меня есть c код как таковой
int childid;
int parentid;
void siginthandler(int param)
{
// if this is the parent process
if(getpid() == parentid){
//handler code which sends SIGINT signal to child process
kill(childid, SIGINT);
}
else // if this is the child process
exit(0);
}
int main()
{
parentid = getpid(); // store parent id in variable parentid, for the parent as well as child process
int pid = fork();
int breakpid;
if(pid != 0){
childid = pid;
breakpid = wait();
printf("pid = %d\n", breakpid);
}
else
sleep(1000);
}
Теперь, когда я запускаю этот код, родительский процесс ждет, пока дочерний процесс спит. Если я сейчас прерву (нажав ctrl+c) родительскую программу, документация UNIX (стандарт POSIX) скажет мне, что функция ожидания должна вернуть -1, а для errno установлено значение EINTR. Однако моя реализация кода убивает дочерний процесс, поскольку родительский процесс отправляет сигнал SIGINT дочернему процессу. Но, что удивительно,(в родительском процессе) ожидание не возвращает pid = -1 с errno, установленным в EINTR. Вместо этого он возвращает идентификатор дочернего процесса, который был убит.
Есть ли объяснение этому?
1 ответ
Когда вы устанавливаете обработчик сигнала с signal()
происходит одна из двух вещей
- Большинство системных вызовов прерываются при возникновении сигнала и устанавливают errno в EINTR.
- Большинство системных вызовов автоматически перезапускается при возникновении сигнала (чтобы они не переставали работать и устанавливали errno в EINTR).
Какой из этих 2 зависит от вашей платформы, от вашей это 2
(возможно, вы не показываете код, который устанавливает обработчик сигнала.)
Если вместо этого вы установите обработчик сигнала с sigaction(), вы можете контролировать, какое поведение 1
или же 2
ты хочешь с SA_RESTART
флаг.