Pergunta

Estou tentando fazer uma tarefa para uma de minhas turmas e nenhum professor/colega está me respondendo.Então, antes de responder, por favor, não me dê respostas exatas!Apenas explicações!

O que preciso fazer é escrever um programa C (timeout.c) que receba dois argumentos de linha de comando, W e T, onde W é a quantidade de tempo em segundos que o processo filho deve levar antes de sair e T é a quantidade de tempo o processo pai deve aguardar o processo filho, antes de encerrar o processo filho e imprimir uma mensagem "Time Out".Basicamente, se W > T, deverá haver um tempo limite.Caso contrário, a criança deverá terminar o seu trabalho e nenhuma mensagem de tempo limite será impressa.

O que eu queria fazer era apenas deixar o processo pai dormir por T segundos e, em seguida, encerrar o processo filho e imprimir o tempo limite; no entanto, a impressão da mensagem de tempo limite não aconteceria em ambos os casos.Como posso verificar se o processo filho foi encerrado?Disseram-me para usar alarm() para isso, mas não tenho ideia de qual uso essa função serviria.

Aqui está meu código caso alguém queira dar uma olhada:

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);
}
Foi útil?

Solução

Embora waitpid forneça o status de retorno do filho, seu uso padrão forçaria o pai a esperar até que o filho terminasse.

Mas sua exigência (se bem entendi) só quer que os pais esperem um certo tempo, alarm() pode ser usado para fazer isso.

Então, você deve usar waitpid() com uma opção específica que retorna imediatamente se o filho ainda não tiver saído (estude os parâmetros da API).Então, se a criança não saísse, você poderia matá-la, caso contrário você já receberia seu status de retorno.

Outras dicas

Você quer o timeout programa para parar mais ou menos assim que o comando terminar, então se você disser timeout -t 1000 sleep 1 o programa de proteção para após cerca de 1 segundo, não após 1000 segundos.

A maneira de fazer isso é definir algum tipo de alarme - classicamente, com o alarm() chamada de sistema e um manipulador de sinal para SIGALRM - e então executar o processo principal wait() ou waitpid() para que quando a criança morrer, ela acorde e recolha o cadáver.Se o processo pai receber o sinal de alarme, ele poderá imprimir sua mensagem e enviar algum tipo de ameaça de morte ao filho.Pode ser sensato tentar SIGTERM e/ou SIGHUP antes de recorrer ao SIGKILL;os sinais SIGTERM e SIGHUP dão à criança errante a chance de limpar, enquanto o SIGKILL não.

Se você souber como gerenciar sinais, poderá capturar SIGALRM e SIGCHLD em seu processo pai.SIGCHLD será gerado quando o cliente terminar e SIGALRM quando o cronômetro expirar.Se o primeiro sinal levantado for SIGALRM, o timeout expirou, caso contrário, se o primeiro SIGNAL que o pai capta for SIGCHLD, o filho parou antes de expirar o timeout.

wait() ou waitpid() ainda seriam necessários para coletar o filho encerrado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top