Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 3948162
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 20, 20262026-05-20T01:20:30+00:00 2026-05-20T01:20:30+00:00

I’m trying to write some code which uses pipes to communicate between a parent

  • 0

I’m trying to write some code which uses pipes to communicate between a parent process and it’s children. However, my pipe seems to give up after the first time I use it (that is, it stops working after the first use of the pipe). I’m not really sure how to fix this problem, and any help will be greatly appreciated. I also know that some of the coding practice I am using in this are not really ideal (mainly use of sleep).

const int READ = 0;
const int WRITE = 1;
char* COOP = "Criminal cooperates\n";
char* SIL = "Criminal doesn't talk\n";

char* reader(int);
void writer(int, char *c);

int main()
{       
    int c1pipe1[2];
    int c1pipe2[2];
    int c2pipe1[2];
    int c2pipe2[2];
    int c1sentence = 0;
    int c2sentence = 0;
    int r;
    int c;
    pipe(c1pipe1);
    pipe(c1pipe2);
    pipe(c2pipe1);
    pipe(c2pipe2);
    int C2;
    int C1 = fork();
    if(C1 > 0)
        C2 = fork();
    if(C1 < 0 || C2 < 0) //error
    {
        perror("fork() failed");
        exit(1);
    }

    else if(C1 == 0)
    {
        close(c1pipe1[WRITE]);
        close(c1pipe2[READ]);
        for(c = 0; c < 10; c++)
        {
            r = rand();
            //printf("C1 rand = %d\n", r%2);
            if(r % 2 == 1)
                writer(c1pipe2[WRITE], "1");
            else
                writer(c1pipe2[WRITE], "0");
            sleep(1);
        }

        exit(0);
    }
    else if(C2 == 0)
    {
        close(c2pipe1[WRITE]);
        close(c2pipe2[READ]);
        for(c = 0; c < 10; c++)
        {
            r = rand();
            //printf("C2 rand = %d\n", r%2);
            if(r % 2 == 1)
                writer(c2pipe2[WRITE], "1");
            else
                writer(c2pipe2[WRITE], "0");
            sleep(1);
        }

        exit(0);
    }
    else //parent
    {
        int buff1; //stores choice of c1
        int buff2; //stores choice of c2
        close(c1pipe1[READ]);
        close(c1pipe2[WRITE]);
        close(c2pipe1[READ]);
        close(c2pipe2[WRITE]);
        for(c = 0; c< 10; c++)
        {
            buff1 = atoi(reader(c1pipe2[READ]));
            buff2 = atoi(reader(c2pipe2[READ]));
            printf("C1's \(%d)\ choice trial %d : %d\n", C1, c+1, buff1);
            printf("C2's \(%d)\ choice trial %d : %d\n", C2, c+1, buff2);
            if(buff1 && buff2) //c1 and c2 cooperate with police
            {
                    c1sentence = c1sentence + 6;
                    c2sentence = c2sentence + 6;
            }
            else if(buff1 || buff2) // one cooperates, one is silent
            {
                if(buff1) // if c1 cooperates and c2 is silent
                {
                    c1sentence = c1sentence + 0;
                    c2sentence = c2sentence + 10;
                }
                else // if c2 cooperates and c1 is silent
                {
                    c1sentence = c1sentence + 10;
                    c2sentence = c2sentence + 0;
                }
            }
            else if(!(buff1 && buff2)) //both c1 and c2 are silent
            {
                c1sentence = c1sentence + 1;
                c2sentence = c2sentence + 1;
            }
            sleep(1);


        }       
        printf("C1 is in jail for %d years total\n", c1sentence);
        printf("C2 is in jail for %d years total\n", c2sentence);
        exit(0);
    }
    exit(0);
}

void writer(int pipe_write_fd, char *c) 
{
    open(pipe_write_fd);
    char* choice = c;
    // Write to the pipe
    write(pipe_write_fd, choice, strlen(choice));
    // Close the pipe
    // (Sends 'end of file' to reader)
    close(pipe_write_fd);
}

char* reader(int pipe_read_fd) 
{
    open(pipe_read_fd);
    // Allocate buffer to store
    // result of read
    int buffer_size = 1024;
    char buffer[buffer_size];

    // Keep reading until we exhaust
    // buffer or reach end of file
    int i = 0;
    while (i < buffer_size
           && read(pipe_read_fd, &buffer[i], 1) > 0)
    { i++; }

    if (i < buffer_size) {
        // Add null termination
        buffer[i] = '\0';
    } else {
        // We exhausted buffer
        fprintf(stderr, "Warning: buffer full.\n");
        buffer[buffer_size-1] = '\0';
    }

    //printf("%s", buffer);

    // Close the pipe
    close(pipe_read_fd);
    return buffer;
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-20T01:20:31+00:00Added an answer on May 20, 2026 at 1:20 am

    You need to close more of the pipes. The child processes must close every pipe file descriptor that they are not using. You have 8 pipe file descriptors; each child process has to close 6 of those – at least! You would be very well advised not to create all the pipes up front as you have done – it is complicated to control things and get all the right descriptors closed.


    Looking at the code more closely, the parent does not write messages to the child processes, so you have twice as many pipes as you need – you only need one pipe for each child process to write back to the parent with.

    You also do not open() already open file descriptors to the pipes…but how did you get the code to compile? You must be missing the correct header (#include <fcntl.h>) for open() and compiling without enough warning options enabled.

    Your variables COOP and SIL are unused in the code presented.


    Your writer() function not only mistakenly tries to open an already closed file descriptor, it also closes it, which means that there is no way to send back the extra messages after the first. You should only close the file descriptor once finished – after the loop in the main program for each child. This is why you only see one message.

    It is also worth getting into the habit of error-checking the return from every system call that can fail. There are a few that can’t fail – getpid() is one such. But I/O operations are notorious for failing for reasons outside the direct control of the program (or, in this case, within the control of the program), so you should check that writes succeed. When you get back an EBADF – bad file descriptor – error, you know something is up.

    You have similar problems with close() (and open()) in reader(), plus the additional problem that you attempt to return a pointer to a local automatic variable – which is not a good idea, ever. Again, a decent compiler (like GCC) with warnings enabled will tell you about such things. I used this command to compile your program:

    gcc -O -std=c99 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
        pipe.c -o pipe
    

    Your child processes are always going to generate the same sequence of (pseudo-)random numbers, which isn’t very exciting. You should probably use something like:

    srand(getpid());
    

    to ensure they get different sequences.


    Your reader() function is both not enthusiastic enough and too enthusiastic about reading the data. You read a single byte at a time, but you then loop to accumulate single bytes, so the code waits around for all 10 results to be known, and then spits everything out at once. Since a 32-bit integer can store a number up to 1,111,111,111 without problem, you would get just one number back from your call to atoi() on the first iteration, which isn’t quite what you wanted.

    Reads and writes on pipes are atomic – in the sense that if the writing process writes 6 bytes and the reading process attempts to read more than 6 bytes, then the packet of 6 bytes will be returned by a single read, even if there are other bytes in the pipe waiting to be read; those extra bytes will be returned on subsequent calls to read().

    So, your reader() function should be passed in a buffer to use, along with its size; the code should attempt to read that buffer size; it should null terminate what it does receive; it can return the pointer to the buffer it was passed; it should error check the returned value from read().

    The code for the two child processes is essentially the same – you should use an appropriately parameterized function rather than writing out the code twice.


    Putting it all together, you end up with something like this (which works fine for me on MacOS X 10.6.6 with GCC 4.5.2):

    #include <errno.h>
    #include <string.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdarg.h>
    #include <stdlib.h>
    
    const int READ = 0;
    const int WRITE = 1;
    
    static char* reader(int fd, char *buffer, size_t bufsiz);
    static void writer(int fd, const char *c);
    static void child_process(int *my_pipe, int *his_pipe);
    
    static void err_exit(const char *fmt, ...)
    {
        va_list args;
        int errnum = errno;
        va_start(args, fmt);
        vfprintf(stderr, fmt, args);
        va_end(args);
        if (errnum != 0)
            fprintf(stderr, "%d: %s\n", errnum, strerror(errnum));
        exit(1);
    }
    
    int main(void)
    {       
        int c1pipe[2];
        int c2pipe[2];
        int c1sentence = 0;
        int c2sentence = 0;
        int c;
    
        if (pipe(c1pipe) != 0 || pipe(c2pipe) != 0)
            err_exit("Failed to open a pipe\n");
    
        int C2 = 0;
        int C1 = fork();
        if (C1 > 0)
            C2 = fork();
    
        if (C1 < 0 || C2 < 0) //error
            err_exit("fork() failed\n");
        else if (C1 == 0)
            child_process(c1pipe, c2pipe);
        else if (C2 == 0)
            child_process(c2pipe, c1pipe);
        else //parent
        {
            int choice1; //stores choice of c1
            int choice2; //stores choice of c2
            char buffer1[BUFSIZ];
            char buffer2[BUFSIZ];
            close(c1pipe[WRITE]);
            close(c2pipe[WRITE]);
            for (c = 0; c< 10; c++)
            {
                choice1 = atoi(reader(c1pipe[READ], buffer1, sizeof(buffer1)));
                choice2 = atoi(reader(c2pipe[READ], buffer2, sizeof(buffer1)));
                printf("C1's (%d) choice trial %d : %d\n", C1, c+1, choice1);
                printf("C2's (%d) choice trial %d : %d\n", C2, c+1, choice2);
                if (choice1 && choice2) //c1 and c2 cooperate with police
                {
                        c1sentence = c1sentence + 6;
                        c2sentence = c2sentence + 6;
                }
                else if (!(choice1 && choice2)) //both c1 and c2 are silent
                {
                    c1sentence = c1sentence + 1;
                    c2sentence = c2sentence + 1;
                }
                else if (choice1) // if c1 cooperates and c2 is silent
                {
                    c1sentence = c1sentence + 0;
                    c2sentence = c2sentence + 10;
                }
                else // if c2 cooperates and c1 is silent
                {
                    c1sentence = c1sentence + 10;
                    c2sentence = c2sentence + 0;
                }
            }       
            printf("C1 is in jail for %d years total\n", c1sentence);
            printf("C2 is in jail for %d years total\n", c2sentence);
        }
        return(0);
    }
    
    static void writer(int pipe_write_fd, const char *c) 
    {
        int len = strlen(c);
        if (write(pipe_write_fd, c, len) != len)
            err_exit("Write failed\n");
    }
    
    static char* reader(int pipe_read_fd, char *buffer, size_t bufsiz) 
    {
        int i = read(pipe_read_fd, buffer, bufsiz-1);
        if (i < 0)
            err_exit("Read failed\n");
        buffer[i] = '\0';
        return buffer;
    }
    
    static void child_process(int *my_pipe, int *his_pipe)
    {
        int c;
        srand(getpid());
        close(my_pipe[READ]);
        close(his_pipe[READ]);
        close(his_pipe[WRITE]);
        for (c = 0; c < 10; c++)
        {
            writer(my_pipe[WRITE], ((rand() % 2) == 1) ? "1" : "0");
            sleep(1);
        }
        close(my_pipe[WRITE]);
    }
    

    Note how the error routine captures errno early – to avoid damaging it. It is one of the perils of using global variables; they may change when you call a function. Don’t use them when you can avoid them (but note that you can’t avoid using errno completely, in general).

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am trying to understand how to use SyndicationItem to display feed which is
I'm trying to decode HTML entries from here NYTimes.com and I cannot figure out
Basically, what I'm trying to create is a page of div tags, each has
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I am trying to loop through a bunch of documents I have to put
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I have this code: - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { NSString *someString = [[NSString
I have some data like this: 1 2 3 4 5 9 2 6
I'm new to using the Perl treebuilder module for HTML parsing and can't figure

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.