Неверная стоимость канала C из родительского процесса - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть эта простая программа, но когда я хотел проверить значение, которое я получаю от ребенка, он возвращает 1995694080 или аналогичные числа.Я немного сбит с толку, как я могу добиться, чтобы получить реальное значение сообщения?Похоже, я получаю какое-то случайное значение мусора из другого места, где я не должен.Я сделал этот канал отправителем на основе учебника, и он в основном работает только тогда, когда я отправляю данные от потомка, это не удается.Любая идея или предложение?

int pipefd[2];

int main()
{
    signal(SIGTERM, handler);
    signal(SIGUSR1, finishedOrder);
    pid_t pid;


    if (pipe(pipefd) == -1)
    {
        perror("Error while making pipe.\n");
        exit(1);
    }

    pid = fork();

    if (pid < 0)
    {
        perror("Fork error.\n");
        exit(1);
    }

    if (pid > 0)
    {
        employer(pid, 4, false);
    }
    else
    {
        employee(getppid());
    }
}

void employer(pid_t pid, int id, bool two)
{
    int rec;

    printf("[Szülő]: várok egy szerelő csapatra! \n");
    sleep(1);

    kill(pid, SIGTERM);

    pause();

    if (two)
    {
        /.../
    }
    else
    {
        printf("[Szülő]: dolgozz a %d. feladaton\n", id);
        close(pipefd[0]);
        write(pipefd[1], &id, sizeof(id)); //this is works.
        close(pipefd[1]);
        sleep(1);

        kill(pid, SIGTERM);

        pause();

        kill(pid, SIGTERM);
    }

    pause();

    close(pipefd[1]);
    read(pipefd[0], &rec, sizeof(rec));

    printf("%d\n", rec); // here I get the strange value

    if (rec == 4)
    {
        printf("[Szülő]: feljegyeztem a módosításokat.\n");
        if (two)
        {
            /**/
        }
        else
        {
            /**/
        }
    }

}

void employee(pid_t emp)
{
    int jobs[2];
    pause();

    printf("[Gyerek]: munkára jelentkezek\n");
    sleep(1);

    kill(emp, SIGTERM);

    pause();

    close(pipefd[1]);

    read(pipefd[0], &jobs[0], sizeof(jobs[0]));
    close(pipefd[0]);
    printf("[Gyerek]: elkezdek dolgozni a %d. feladaton.\n", jobs[0]);
    sleep(1);
    kill(emp, SIGUSR1);
    pause();

    sleep(1);
    read(pipefd[0], &jobs[1], sizeof(jobs[1]));


    if (jobs[1] != 0)
    {
        printf("[Gyerek]: elkezdek dolgozni a %d. feladaton.\n", jobs[1]);
        sleep(1);

        kill(emp, SIGUSR1);
    }

    close(pipefd[0]);
    fflush(NULL);
    int msg = 4;
    printf("%d\n", msg);
    write(pipefd[1], &msg, sizeof(msg));
    close(pipefd[1]);

    sleep(1);
    kill(emp, SIGTERM);
}

void handler(int signum)
{
}

void finishedOrder()
{
}

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

В вашей функции employer() вы закрываете конец чтения канала с помощью close(pipefd[0]);, а затем пытаетесь читать с него позже с помощью read(pipefd[0], &rec, sizeof(rec));

Попытка чтения с закрытого fd , вероятноприводит к странным значениям. будет делать то, что Джонатан Леффлер говорит, что будет делать.

rustyx прав в комментариях - проверка возвращаемого значения read() - хорошая идея, потому что она обнаружит ошибку такого рода..

0 голосов
/ 27 ноября 2018
read(pipefd[0], &rec, sizeof(rec));

Вы не проверяете значение, возвращаемое read, чтобы увидеть, сколько данных вы получили.Если вы это сделали, вы, вероятно, обнаружите, что это не то, что вы ожидаете, потому что ранее в своем коде вы сделали это ...

    close(pipefd[0]);

Вы не можете читать из файлового дескриптора после того, какзакрыл это.И что еще более важно, созданная вами «труба» не является двунаправленной.Если вы хотите отправлять и получать, вам нужно сделать два вызова на pipe, чтобы получить две пары файловых дескрипторов.

Учитывая, что вы также делаете close(pipefd[1]) перед read, что означает, что вы 'закрыв оба конца канала, похоже, вы неправильно поняли, для чего цель close ing в этом контексте.Дочерний и родительский close конец канала, который они не используют - вот и все.Это ничего не значит о том, кто читает или пишет в канал.

...