Вопрос

Я пытаюсь выполнить задание для одного из моих занятий, но профессора/однокурсники мне не отвечают.Поэтому, прежде чем ответить, пожалуйста, не давайте мне точных ответов!Только объяснения!

Что мне нужно сделать, так это написать программу на языке C (timeout.c), которая принимает два аргумента командной строки, W и T, где W — это количество времени в секундах, которое должно пройти дочернему процессу перед выходом, а T — это количество времени. родительский процесс должен дождаться дочернего процесса, прежде чем убить дочерний процесс и распечатать сообщение «Time Out».По сути, если W > T, должен быть тайм-аут.В противном случае дочерний процесс должен завершить свою работу, и тогда сообщение о тайм-ауте не будет выведено.

Я хотел просто заставить родительский процесс спать в течение T секунд, а затем убить дочерний процесс и распечатать тайм-аут, однако распечатка сообщения о тайм-ауте не произойдет в обоих случаях.Как проверить, завершен ли дочерний процесс?Мне сказали использовать для этого сигнализацию(), однако я понятия не имею, какую пользу может принести эта функция.

Вот мой код на случай, если кто-то захочет посмотреть:

void handler (int sig) {
    return;
}

int main(int argc, char* argv[]){
    if (argc != 3) {
    printf ("Please enter values W and T, where W\n");
    printf ("is the number of seconds the child\n");
    printf ("should do work for, and T is the number\n");
    printf ("of seconds the parent process should wait.\n");
    printf ("-------------------------------------------\n");
    printf ("./executable <W> <T>\n");
    }

    pid_t pid;
    unsigned int work_seconds = (unsigned int) atoi(argv[1]);
    unsigned int wait_seconds = (unsigned int) atoi(argv[2]);

    if ((pid = fork()) == 0) {
        /* child code */
        sleep(work_seconds);
        printf("Child done.\n");
        exit(0);
    }

    sleep(wait_seconds);
    kill(pid, SIGKILL);
    printf("Time out.");

    exit(0);
}
Это было полезно?

Решение

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

Но ваше требование (если я правильно понял) хочет только родителя ждать определенного времени, тревоги () можно использовать для этого.

Затем вы должны использовать waitpid () с определенной опцией, которая немедленно возвращается, если ребенок еще не вышел (изучите параметры API).Так что, если ребенок не выходил, вы можете убить его, иначе вы уже получаете его возвратный статус.

Другие советы

Вы хотите timeout программа остановится более или менее сразу после завершения команды, поэтому, если вы скажете timeout -t 1000 sleep 1 программа защиты останавливается примерно через 1 секунду, а не через 1000 секунд.

Способ сделать это — установить какой-нибудь будильник — классически, с помощью alarm() системный вызов и обработчик сигнала для SIGALRM — а затем выполнить основной процесс wait() или waitpid() чтобы, когда ребенок умрет, он просыпался и собирал труп.Если родительский процесс получает сигнал тревоги, он может распечатать свое сообщение и послать своего дочернему процессу какую-либо угрозу смерти.Возможно, было бы разумно попробовать SIGTERM и/или SIGHUP, прежде чем прибегать к SIGKILL;сигналы SIGTERM и SIGHUP дают ошибочному дочернему элементу возможность очиститься, тогда как SIGKILL этого не делает.

Если вы знаете, как управлять сигналами, вы можете поймать Sigalrm и Sigchld в своем родительском процессе.SIGCHLD будет поднят, когда клиент заканчивается, и Sigalrm, когда истекает таймер.Если первый поднятый сигнал является SIGALRM, время ожидания, иначе, в противном случае, если первый сигнал, который родитель уловит Sigchld, ребенок остановился до истечения тайм-аута.

ждать () или weepepid () все равно потребуется для сбора прекращенного ребенка.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top