Использование alarm () для реализации тайм-аута процесса

Я пытаюсь создать механизм, который будет ожидать дочерний процесс в течение определенного периода времени и соответственно выполнять дополнительные действия.

Я пробовал следующее:

#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <iostream>

volatile sig_atomic_t p_flag = false;

pid_t makeproc ()
{
pid_t pid;

pid = fork();

// parent
if (pid) return pid;

//child
std::cout << "Child created\n";
sleep(5);
exit(0);
}

void sig_handle (int sig)
{
std::cout << "Handler called\n";
p_flag = true;
}

int main() {
int status;
pid_t child;
int ret;

signal (SIGALRM, sig_handle);
alarm(2);

child = makeproc();
pid_t p = waitpid(-1, &status, 0);
std::cout << "PID: " << p << " FLAG: " << p_flag;

return 0;
}

Что я получаю из этого, так это то, что waitpid() не прерывается SIGALRM и родитель продолжает ждать, пока процесс не завершится. Выход показывает, что SIGALRM генерируется и вызывается обработчик.

Child created
Handler called
PID: 31683 FLAG: 1

Я не могу выступить kill() в обработчике убить ребенка. Как я могу получить wait() чтобы вернуться, когда SIGALRM Поднялся?

0

Решение

Скорее всего, в вашей версии ОС, signal вызов устанавливает обработчик с SA_RESTART флаг установлен. Когда этот флаг установлен, системные вызовы автоматически перезапускаются после обработчика сигнала.

Чтобы взять это под контроль, вместо использования устаревших и устаревших signalиспользовать sigactionи убедитесь, что вы не указали флаг SA_RESTART. Это должно исправить вашу проблему.

1

Другие решения

Других решений пока нет …