C-Программа не завершится через 30 секунд

Нас попросили предложить пользователю ввести фразы и продолжать спрашивать их, пока они не получат нужную фразу, в течение 30 секунд. Вот что я придумал:

#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void childprocess(void)
{
    int start = 30;
    do
    {
        start--;
        sleep(1);
    } while (start >= 0);
    printf("Time ran out!\n");
    exit(EXIT_SUCCESS);
}

int main(void)
{
    pid_tiChildID;/* Holds PID of current child */
    char word[100] = "cat";
    char input[100];
    int length;
    iChildID = fork();
    if (0 > iChildID)
    {
        perror(NULL);
        return 1;
    }
    else if (0 == iChildID)
    {
        childprocess();
        return 0;
    }
    /* Parent process */
    while (1)
    {
        fgets(input, sizeof(input), stdin);
        length = strlen(input);
        if (input[length - 1] == '\n')
        {
            --length;
            input[length] = '\0';
        }
        if (strcmp(word, input) == 0)
            break;
        printf("Try again\n");
    }
    kill(iChildID, SIGUSR1);/* terminate repeating message */
    printf("Finally!\n");
    return 0;
}

Проблема: через 30 секунд он печатает «Время истекает», но не завершается. Как закрыть программу через 30 секунд? Любая помощь?


person Anita Dick    schedule 10.11.2016    source источник
comment
почему вы ожидаете, что он завершится, когда он застрял в while(1)?   -  person John3136    schedule 10.11.2016
comment
Это не 30 секунд. Это будет 30 итераций. Чтобы получить 30 секунд, вычтите текущее время из времени начала и найдите 30.   -  person Ryan    schedule 10.11.2016
comment
Если вы собираетесь сделать это таким образом, используйте sleep(30);, чтобы заснуть на 30 секунд вместо цикла. Ребенок должен отправить сигнал родителю, когда он просыпается, и сообщать об истечении времени только в случае успеха. Родитель должен обработать сигнал и выйти, когда он будет получен. Когда дан правильный ввод, он может принять решение игнорировать сигнал, чтобы он не прерывался преждевременно. В качестве альтернативы вы можете просто иметь код в одном процессе, обрабатывающем SIGALRM, и использовать системный вызов alarm() для установки тайм-аута. Или используйте один из различных более современных вариантов, но alarm() вам подойдет.   -  person Jonathan Leffler    schedule 10.11.2016


Ответы (1)


Здесь вы используете fork, который создает два отдельных процесса с двумя разными PID. Вы убиваете дочерний процесс, но родитель все еще работает, поэтому программа просто не выходит.

Вы могли бы также использовать pthread вместо fork с остатками в одном и том же одном процессе, но то, чего вы пытаетесь достичь, просто с помощью функции будильника. Вам не нужно управлять каким-либо другим процессом. Просто используйте будильник.

#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

static void ALARMhandler(int sig)
{
    printf("Time ran out!\n");
    exit(EXIT_SUCCESS);
}

int main(void)
{
    char word[100] = "cat";
    char input[100];
    size_t length;

    signal(SIGALRM, ALARMhandler);
    alarm(30);

    while(1) {
        fgets(input, sizeof(input),stdin);
        length = strlen(input);
        if(input[length-1] == '\n') {
            --length;
            input[length] = '\0';
        }           
        if (strcmp(word,input) == 0)
            break;
        printf("Try again\n");
    }

    /* terminate repeating message */
    printf("Finally!\n");
    return 0;   
} 

Надеюсь, поможет !!

person Kalrav J Parsana    schedule 10.11.2016