0
    for (int i = 0; i < number_processes; i++){

        while (read(fps[i][0], &each_record_read, sizeof(struct rec)) > 0){
            if (records_container[i] == NULL){
                records_container[i] = &each_record_read;
            }
        } // I want to do something to records_container here.
    }

I have a program that its purpose is for the parent process to read data from each pipe that connects to several children.

I have define an array called records_container that contains each data type that I am going to read from the pipe, and I want to do something to this array after the while loop.

My question is this: when parent is loading data to records_container this array, is parent loading speed fast enough so that when I want to do something to records_container, I can always make sure all data is already being loaded perfectly?

Let's assume records_container is {0, 0, 0, 0} in this case (I know I want to load struct rec, but this doesn't matter really), the ideal situation that I want it to happen is that I want to deal with the loaded array, which is {1, 2, 3, 4} in this case, will parent read each number fast enough (which is 1, 2, 3, 4 from each pipe in this case) so that I won't deal with something like {1, 2, 0, 0}, or {1, 0, 0, 0} ... that kind stuff?

14
  • 2
    Your loop isn't going to process the second pipe until it gets EOF from the first pipe. And then it won't process the third pipe until it gets EOF from the second pipe. And so on.
    – Barmar
    Commented Mar 18, 2019 at 2:03
  • It sounds like what you're really asking is whether a read on the pipe will read everything that the child wrote, or just read part of it.
    – Barmar
    Commented Mar 18, 2019 at 2:06
  • Yes I kind of feel that as well but really not sure, thanks for pointing that out. Is there any way that can let me skip reading from the first pipe and immediately go to next pipe for reading? Commented Mar 18, 2019 at 2:06
  • Reads and writes on a pipe are atomic, see unix.stackexchange.com/questions/346755/…
    – Barmar
    Commented Mar 18, 2019 at 2:07
  • Yes exactly, I want it to be read a part of it, not the entire pipe as once, but I kind have no clue how to achieve this asynchronous goal. Commented Mar 18, 2019 at 2:08

1 Answer 1

1

This does not work.

while (read(fps[i][0], &each_record_read, sizeof(struct rec)) > 0)

is wrong and you can get a short read. When dealing with a structured pipe, we typically use something like this:

ssize_t read_block(int source, void *buffer, ssize_t len)
{
    char *work = buffer;
    while (len) {
        ssize_t delta = read(source, work, len);
        if (delta < 0) return -1; /* ERROR */
        if (delta == 0) return 0; /* EOF */
        work += delta;
        len -= delta;
    }
}

/* ... */

    while (read_block(fps[i][0], &each_record_read, sizeof(struct rec)) > 0){

Now it works.

2
  • I am kind of new to this thing, can this code implement the "jump read pipe" functionality? Commented Mar 18, 2019 at 3:39
  • @DigitalSoul: What does jump read pipe even mean? It doesn't seem to be in the question.
    – Joshua
    Commented Mar 18, 2019 at 13:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.