C Программа fork () повторяет результаты - PullRequest
1 голос
/ 28 апреля 2020

Я изучаю fork () и pipe, написав простую программу. У меня он успешно возвращает результаты, но один из результатов повторяется. Я экспериментировал с кодом, чтобы выяснить его, но не смог понять его правильно.

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

Текущий код:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <wait.h>
#include <time.h>

#define MAX 150
#define PipeStdIn 0             //UNIX StdIn
#define PipeStdOut 1            //UNIX StdOut

void lifeSupport();
void navigation();

int main()
{
    const char *message = {"Calibrate Systems\n"};
    int pipes[2], ret;
    char buf[MAX + 1];


    if(pipe(pipes) == 0)
    {
        if(fork() == 0)
        {
            ret = read(pipes[PipeStdIn], buf, MAX);
            printf("Life Support receives instruction: %s\n", buf);

            sleep(5);

            sleep(4);

            const char *breathGL = {"Breathing gas levels have been adjusted\nAdjustment time: 5 seconds\nLighting and temperature levels have been adjusted\nAdjustment time: 4 seconds\n"};

            ret = write(pipes[PipeStdOut], breathGL, strlen(breathGL) + 1);
        }
        else
        {       
            ret = write(pipes[PipeStdOut], message, strlen(message) + 1);                   //write

            ret = wait(NULL);

            ret = read(pipes[PipeStdIn], buf, MAX);

            time_t now;
            time(&now);
            printf("Report received: %s\n", buf);
            printf("Report time: %s\n", ctime(&now));
        }
    }

    if(pipe(pipes) == 0)
    {
        if(fork() == 0)
        {
            ret = read(pipes[PipeStdIn], buf, MAX);
            printf("Navigation receives instruction: %s\n", buf);

            sleep(3);

            const char *nav = {"Navigation system has been adjusted\nAdjustment time: 3 seconds\n"};

            ret = write(pipes[PipeStdOut], nav, strlen(nav) + 1);
        }
        else
        {       
            ret = write(pipes[PipeStdOut], message, strlen(message) + 1);                   //write

            ret = wait(NULL);

            ret = read(pipes[PipeStdIn], buf, MAX);

            time_t now;
            time(&now);
            printf("Report received: %s\n", buf);
            printf("Report time: %s\n", ctime(&now));
        }       
    }

    close(pipes[PipeStdIn]);
    close(pipes[PipeStdOut]);

    return 0;
}

Ожидаемые результаты:

Life Support receives instruction: Calibrate Systems

Report received: Breathing gas levels have been adjusted
Adjustment time: 5 seconds
Lighting and temperature levels have been adjusted
Adjustment time: 4 seconds

Report time: Tue Apr 28 08:48:49 2020

Navigation receives instruction: Calibrate Systems

Report received: Navigation system has been adjusted
Adjustment time: 3 seconds

Report time: Tue Apr 28 08:48:52 2020

Текущие результаты:

Life Support receives instruction: Calibrate Systems

Navigation receives instruction: Calibrate Systems

Report received: Navigation system has been adjusted
Adjustment time: 3 seconds

Report time: Tue Apr 28 08:48:49 2020

Report received: Breathing gas levels have been adjusted
Adjustment time: 5 seconds
Lighting and temperture levels have been adjusted
Adjustment time: 4 seconds

Report time: Tue Apr 28 08:48:49 2020

Navigation receives instruction: Calibrate Systems

Report received: Navigation system has been adjusted
Adjustment time: 3 seconds

Report time: Tue Apr 28 08:48:52 2020

1 Ответ

1 голос
/ 28 апреля 2020

Если объяснение неясно из комментария, вам нужно переместить полную секунду if(fork() == 0) {...} else {...} внутри первого else, чтобы предотвратить выполнение этого блока и родителем, и потомком. После перемещения if(fork() == 0) {...} else {...} вверх ваша логика c будет выглядеть следующим образом:

    if(pipe(pipes) == 0)
    {
        if(fork() == 0)
        {
            ret = read(pipes[PipeStdIn], buf, MAX);
            ...
            ret = write(pipes[PipeStdOut], breathGL, strlen(breathGL) + 1);
        }
        else
        {       
            ret = write(pipes[PipeStdOut], message, strlen(message) + 1);
            ...

            if(fork() == 0)
            {
                ret = read(pipes[PipeStdIn], buf, MAX);
                ...
                const char *nav = "Navigation system has been adjusted\n"
                                    "Adjustment time: 3 seconds\n";

                ret = write(pipes[PipeStdOut], nav, strlen(nav) + 1);
            }
            else
            {       
                ret = write(pipes[PipeStdOut], message, strlen(message) + 1);
                ...
                // time_t now;
                time(&now);
                printf("Report received: %s\n", buf);
                printf("Report time: %s\n", ctime(&now));
            }       
        }
    }

    close(pipes[PipeStdIn]);
    close(pipes[PipeStdOut]);

Также обратите внимание, что компиляция C объединит смежные строки в одну во время компиляции, что позволит вам разбить длинный строки в серии строк в двойных кавычках, которые будут объединены во время компиляции, например,

        const char *breathGL = "Breathing gas levels have been adjusted\n"
                        "Adjustment time: 5 seconds\n"
                        "Lighting and temperature levels have been adjusted\n"
                        "Adjustment time: 4 seconds\n";

и

            const char *nav = "Navigation system has been adjusted\n"
                                "Adjustment time: 3 seconds\n";

(также обратите внимание, что добавление {...} не требуется)

Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

...