0

After producing SIZE items, the producer process should write to the fd_pipe_p2c pipe and be read by the consumer process, which then outputs what it is consuming. After that the consumer should write back to the producer via the pipe_fd_c2p pipe to let it know there's more room in the buffer.

The cnt int doesn't seem to reach SIZE, which I expect it to do after the producer function produces SIZE items. Therefore the consumer function never receives what is produced.

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10

int shared_arr[SIZE];
int cnt = 0, in = 0, out = 0;
int fd_pipe_c2p[2], fd_pipe_p2c[2];

void consumer();
void producer();

int main() {
    pipe(fd_pipe_c2p); // consumer to producer
    pipe(fd_pipe_p2c); // producer to consumer

    if (fork() == 0) {
        // child process
        consumer();
    } else {
        // parent process
        producer();
        sleep(3);
    }

    exit(0);
}

void consumer() {
    // consumer process
    close(fd_pipe_c2p[0]);
    while (1) {
        while (cnt == 0) {
            // give up everything
            write(fd_pipe_c2p[1], &cnt, 1);
            write(fd_pipe_c2p[1], shared_arr, sizeof(shared_arr));

            // read in cnt?
            read(fd_pipe_p2c[0], &cnt, 1);
            if (cnt > 0) { // if we have something, break out of inner loop
                break;
            }
        }

        read(fd_pipe_p2c[0], shared_arr, sizeof(shared_arr)); // read in array

        int n = shared_arr[out]; // get value to consume

        fprintf(stderr, "I am consuming.......%d\n", n, out);

        out = (out + 1) % SIZE; // move out forward?
        cnt--; // decrease count
    }
}

void producer() {
    // producer process
    close(fd_pipe_p2c[0]);
    while (1) {
        // read in cnt, if it's not == SIZE then produce something
        read(fd_pipe_c2p[0], &cnt, 1);
        while (cnt == SIZE)  {
            // write to consumer, we've produced something for it:
            write(fd_pipe_p2c[1], &cnt, 1);
            write(fd_pipe_p2c[1], shared_arr, sizeof(shared_arr));
        }

        // cnt != SIZE, so let's produce something:
        shared_arr[in] = rand() % 100;
        fprintf(stderr, "I am producing......%d...%d\n", shared_arr[in], in);
        in = (in + 1) % SIZE;
        cnt++;
    }
}


}

Perhaps an example of the expected output would explain better:

I am producing......26...0.

I am producing......34...1.

I am producing......6...2.

I am producing......1...3.

I am producing......84...4.

I am producing......35...5.

I am producing......89...6.

I am producing......38...7.

I am producing......65...8.

I am producing......78...9.

 Check to see something available.

I am producing......80...0.

I am consuming......26  0       

I am producing......67...1.

I am consuming......34  1       

I am producing......59...2.

I am consuming......6   2       

I am producing......52...3.

I am consuming......1   3       

I am producing......85...4.

I am consuming......84  4       

I am producing......79...5.

I am consuming......35  5       

I am producing......94...6.

I am consuming......89  6       

I am producing......58...7.

I am consuming......38  7       

I am producing......74...8.

I am consuming......65  8       

I am producing......67...9.

I am consuming......78  9       

 Check to see something available.

Instead, this is my current output:

I am producing......83...0
I am producing......86...1
I am producing......77...2
I am producing......15...3
I am producing......93...4
I am producing......35...5
I am producing......86...6
I am producing......92...7
I am producing......49...8
I am producing......21...9
I am producing......62...0
I am producing......27...1
I am producing......90...2
I am producing......59...3
I am producing......63...4
I am producing......26...5
I am producing......40...6
I am producing......26...7
I am producing......72...8
I am producing......36...9
I am producing......11...0
I am producing......68...1
I am producing......67...2
I am producing......29...3
I am producing......82...4
I am producing......30...5
I am producing......62...6
I am producing......23...7
I am producing......67...8
I am producing......35...9
I am producing......29...0
I am producing......2...1
I am producing......22...2
I am producing......58...3
I am producing......69...4
I am producing......67...5
I am producing......93...6
I am producing......56...7
I am producing......11...8
I am producing......42...9
I am producing......29...0
Nathan
  • 246
  • 1
  • 4
  • 10
  • 1
    Mismatch between format string and parameter list in `fprintf(stderr, "I am consuming.......%d\n", n, out);`. – Jonathan Leffler Mar 07 '18 at 04:48
  • 1
    Code is having trouble with I/O yet code lacks checks of the return values of `read(), write()`. Best to add checks there. – chux - Reinstate Monica Mar 07 '18 at 04:49
  • `while (cnt == SIZE) ;` doesn't change `cnt` at all, so once the loop starts, it will not stop until you get stroppy and kill the program. – Jonathan Leffler Mar 07 '18 at 04:50
  • 1
    Note that once the process has forked, the parent and child processes no longer share `shared_arr` — each has their own copy of the array. You have `write(fd_pipe_c2p[1], &cnt, 1);` — that writes one byte of the integer `cnt`. That's not what you want. This is prevalent in both read and write operations. – Jonathan Leffler Mar 07 '18 at 04:51
  • Also, it seems a bit odd for the producer to consume some information from the consumer before it produces anything. You are going to need to rethink the code from the ground up. Make sure you know exactly what information is supposed to be exchanged when, and how the other process will know there's information ready, etc. – Jonathan Leffler Mar 07 '18 at 04:56
  • It has occurred to me that I posted slightly outdated code, I have changed it. – Nathan Mar 07 '18 at 05:27
  • The revised code gets rid of one infinite loop; that's good. You've not done anything about reading and writing single bytes instead of integers when you try to pass the count around. If you're on a big-endian machine (PowerPC, SPARC, …) then you'll always be transferring a count of 0. On a little-endian machine (Intel, …), you'll be passing the low-order 8 bits, which is probably "OK", but it would be better to design it so that's clear (use a `char` for the type of `cnt`, for example). – Jonathan Leffler Mar 07 '18 at 08:17
  • 1
    The producer increments `cnt` but then the next thing it does is read a byte into `cnt` making the increment more or less pointless. – Michael Burr Mar 07 '18 at 08:21
  • 1
    The consumer writes 0 to the producer; the producer reads 0 and notes that it is not the same as size, so it ignores the `sizeof(shared_arr)` bytes (all zeroes) that the consumer also wrote on the pipe. That means it doesn't write anything to the consumer. You still have quite a lot of work to do. It isn't clear to me how it is supposed to behave. Your description starts "after producing SIZE items, the producer …", but the code doesn't have the producer producing SIZE items at any point. So it is hard to know what should be done. – Jonathan Leffler Mar 07 '18 at 08:21
  • Actual task i'm trying to complete: Producer process produces an item and add it into the buffer if it is not full; and then notices the consumer process that some items in the buffer and ready to be consumed via a pipe (from producer to consumer); Once Consumer received the information and then take an item one after another from the buffer until the buffer become empty. During this process, Consumer needs to notice the producer that the buffer is not full via a pipe (from consumer to producer); These two processes cooperate each other until the processes are terminated. – Nathan Mar 07 '18 at 08:33

0 Answers0