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