Это наша задача: написать три программы, которые взаимодействуют через очередь fifo. Первая программа отправит четные числа, вторая программа отправит нечетные числа, а третья программа получит числа и сложит их вместе. Все процессы должны отображать результаты своей работы на экране. Я пытался это решить, но мой код не работает должным образом, возможно, проблема в 3 программе, пожалуйста, помогите. Первая прога должна отправлять четные числа, вторая нечетные числа, а третья должна принимать и складывать эти числа вместе (сумма). Первая и вторая программы вроде бы выполняют свою задачу, а третья нет и зависает. Мой код:

//1 программа

 #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>


void prog1(int descriptor,char *fifo)
{

        int a=0;
        int i=0;
while (i!=10)
    {

            a+=2;
        descriptor = open(fifo, O_WRONLY);
        write(descriptor,&a, sizeof(a)+1);
        puts("");
  printf(" Even number : %d",a);
        close(descriptor);
        i++;

    }
}
int main()
{
    int descriptor;
    char * fifo = "/tmp/myfifo_file";
   mkfifo(fifo, 0666);
 prog1(descriptor,fifo);
    return 0;
}

//2 программа

    #include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>

void prog2(int descriptor,char *fifo)
{

        int b=1;
        int i=0;

while (i!=10)
    {


        descriptor = open(fifo, O_WRONLY);
        write(descriptor, &b, sizeof(b)+1);
        puts("");
        printf("Odd number : %d",b);
        b+=2;
        close(descriptor);
       i++;

    }
}
int main()
{
    int descriptor;
    char * fifo = "/tmp/myfifo_file";
   mkfifo(fifo, 0666);
 prog2(descriptor,fifo);
    return 0;
}

//3 программа

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>


void prog3(int descriptor,char *fifo)
{

        int *a;
        int *b;
        int i=0;
while (i!=10)
    {


        descriptor = open(fifo, O_RDONLY);
        read(descriptor,a, sizeof(a));
        close(descriptor);
        descriptor = open(fifo, O_RDONLY);
        read(descriptor,b, sizeof(b));
        close(descriptor);
        printf("Sum : %d",(*a)+(*b));
        i++;

    }
}
int main()
{
    int descriptor;
    char * fifo = "/tmp/myfifo_file";
   mkfifo(fifo, 0666);
 prog3(descriptor,fifo);
    return 0;
}
0
HIP HOP 23 Окт 2019 в 17:12
3
Что происходит не так? Пожалуйста, включите более подробную информацию о том, что на самом деле делает код, по сравнению с тем, что он должен делать.
 – 
OrdoFlammae
23 Окт 2019 в 17:13
Первая прога должна отправлять четные числа, вторая нечетные числа, а третья должна принимать и складывать эти числа вместе (сумма). Первая и вторая программы вроде бы выполняют свою задачу, а третья нет и зависает.
 – 
HIP HOP
23 Окт 2019 в 17:23
1
Пожалуйста, отредактируйте свой вопрос и добавьте туда всю запрошенную информацию или разъяснения вместо того, чтобы писать комментарии.
 – 
Bodo
23 Окт 2019 в 17:46
1
Если вы хотите записать двоичные целые значения в программах 1 и 2, вы должны использовать write(descriptor, &b, sizeof(b));. Ваша текущая программа интерпретирует число, хранящееся в b, как адрес, и считывает с этого адреса на один байт больше, чем размер int. Это неопределенное поведение. Ваша программа будет отправлять мусорные данные или даже может дать сбой. Некоторые ошибки в вашем коде должны вызывать предупреждения компилятора. Возможно, вам нужно включить предупреждения. Пожалуйста, исправьте все предупреждения.
 – 
Bodo
23 Окт 2019 в 17:55
1
У вас была такая же ошибка в прог3. Теперь вы используете неинициализированные указатели a и b в prog3. Не используйте sizeof(b)+1. Это также будет читать байт после конца памяти, которая содержит переменную b. Сравните с кодом в моем предыдущем комментарии. Кстати: нет гарантии, что программа prog3 будет считывать одно значение из программы prog1 и одно значение из программы prog2. Также может случиться, что, например. сначала прог1 записывает все значения, затем прог2 записывает все значения.
 – 
Bodo
23 Окт 2019 в 18:18

1 ответ

Помимо ошибок с использованием правильного адреса и размера данных, которые вы хотите прочитать, основная ошибка заключается в том, что вы не должны многократно открывать и закрывать FIFO в цикле.

Открытие FIFO для чтения или записи будет заблокировано до тех пор, пока другой конец также не будет открыт. Таким образом, и prog1, и prog2 будут ждать, пока prog3 откроет FIFO для чтения, а prog3 будет ждать, пока хотя бы одна из prog1 и prog2 не откроет FIFO для записи.

Закрытие FIFO на стороне записи приведет к состоянию EOF на стороне чтения. Закрытие FIFO на стороне чтения вызовет ошибку «сломанной трубы» на стороне записи.

В программах также отсутствует обработка ошибок. mkfifo, open, read, write, close могут возвращать ошибку, read и write также могут возвращать число байтов меньше, чем вы хотели прочитать или записать. Этого, вероятно, не произойдет с вашим небольшим объемом данных в вашем примере, но вы, скорее всего, заметите это, когда попытаетесь передать большие объемы данных.

Вот улучшенные версии ваших программ:

Прог1

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>


void prog1(char *fifo)
{
    int descriptor;
    int a=0;
    int i=0;
    descriptor = open(fifo, O_WRONLY);
    while (i!=10)
    {

        a+=2;
        write(descriptor,&a, sizeof(a));
        printf("Even number %d : %d\n", i, a);
        i++;
    }
    close(descriptor);
}

int main(void)
{
    char * fifo = "/tmp/myfifo_file";
    mkfifo(fifo, 0666);
    prog1(fifo);
    return 0;
}

Прог2

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>

void prog2(char *fifo)
{
    int descriptor;
    int b=1;
    int i=0;

    descriptor = open(fifo, O_WRONLY);

    while (i!=10)
    {
        write(descriptor, &b, sizeof(b));
        printf("Odd number %d: %d\n", i, b);
        b+=2;
        i++;
    }
    close(descriptor);
}

int main(void)
{
    char * fifo = "/tmp/myfifo_file";
    mkfifo(fifo, 0666);
    prog2(fifo);
    return 0;
}

Prog3

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <string.h>


void prog3(char *fifo)
{
    int descriptor;
    int a;
    int b;
    int i=0;

    descriptor = open(fifo, O_RDONLY);

    while (i!=10)
    {
        read(descriptor,&a, sizeof(a));
        read(descriptor,&b, sizeof(b));
        printf("Sum %d: %d + %d = %d\n", i, a, b, a+b);
        i++;
    }

    close(descriptor);
}

int main(void)
{
    char * fifo = "/tmp/myfifo_file";
    mkfifo(fifo, 0666);
    prog3(fifo);
    return 0;
}

При запуске программ я получаю этот (изменяющийся) вывод:

$ ./prog1&./prog2&
[1] 8410
[2] 8411
$ ./prog3         
Sum 0: 1 + 2 = 3
Odd number 0: 1
Even number 0 : 2
Odd number 1: 3
Sum 1: 3 + 4 = 7
Even number 1 : 4
Odd number 2: 5
Sum 2: 5 + 6 = 11
Odd number 3: 7
Even number 2 : 6
Odd number 4: 9
Even number 3 : 8
Sum 3: 7 + 9 = 16
Odd number 5: 11
Even number 4 : 10
Odd number 6: 13
Sum 4: 8 + 11 = 19
Even number 5 : 12
Odd number 7: 15
Sum 5: 10 + 13 = 23
Even number 6 : 14
Odd number 8: 17
Sum 6: 12 + 15 = 27
Odd number 9: 19
Even number 7 : 16
Sum 7: 14 + 17 = 31
Even number 8 : 18
Sum 8: 16 + 19 = 35
Even number 9 : 20
Sum 9: 18 + 20 = 38
[2]  + 8411 done       ./prog2
[1]  + 8410 done       ./prog1
0
Bodo 25 Окт 2019 в 12:14