Когда функция 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()происходит одна из двух вещей

  1. Большинство системных вызовов прерываются при возникновении сигнала и устанавливают errno в EINTR.
  2. Большинство системных вызовов автоматически перезапускается при возникновении сигнала (чтобы они не переставали работать и устанавливали errno в EINTR).

Какой из этих 2 зависит от вашей платформы, от вашей это 2 (возможно, вы не показываете код, который устанавливает обработчик сигнала.)

Если вместо этого вы установите обработчик сигнала с sigaction(), вы можете контролировать, какое поведение 1 или же 2 ты хочешь с SA_RESTART флаг.

Другие вопросы по тегам