Waitpid прерван системным вызовом

Я разветвляю дочерний процесс для запуска команды, используя execve, Я устанавливаю и определяю 3 обработчика сигналов: SIGCHLD,SIGINT и SIGSTP следующим образом:

void sigchld(int sig)
{
while((pid=waitpid(-1,&stat,WNOTRACE|WNOHANG))>0)
{
  if(WIFEXITED(stat))
    //normal exit: Delete child from job list
  if(WIFSIGNALED(stat))
    //interrupted by signal: delete job from job list
  if(WIFSTOPPED(stat))
   //Stopped: put child in background
 }
}

//SIGINT Handler:
kill(-pid,sig)

//SIGSTOPPED Handler:
kill(-pid,sig)

Теперь, когда я запускаю процесс и помещаю его в фоновый режим (ctrl z) в цикле (100 раз), в большинстве случаев я получаю ошибку: waitpid error: Interrupted system call

Почему я это получаю?

2 ответа

Прерванный системный вызов:

Если процесс поймал сигнал, в то время как процесс был заблокирован в "медленном" системном вызове, то системный вызов был прерван.

Проблема в том, что функция waitpid была прервана из-за получения сигнала, отправленного вызывающим процессом.

Waitpid - это прерванный системный вызов. Итак, проблема с прерванным системным вызовом заключается в том, что теперь мы должны явно обработать возврат ошибки.

Вы должны обработать ошибку в waitpid, используя errno.

Прерванный системный вызов означает, что, например, оператор read выполнен, чтение будет читать входные данные из stdin, между чтением происходит сигнал, теперь система должна обработать этот сигнал, теперь чтение будет завершено, и установите для ошибки значение EINTR.

У меня тоже была эта проблема. Когда я зарегистрировал свой обработчик, я использовал обработчик sigaction, который выглядит немного иначе, чем здесь. В моем случае я не включил флаг SA_RESTART. Включение этого обработчика означает, что системные вызовы автоматически перезапускаются при прерывании.

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