Frage

The idea is to create a binary process tree that sends information down the tree, then sends values back up the tree, aggregating information as it ascends.

The problem I am having is with using select() to determine when pipes are ready to be read from. In what I have written so far, the first pipe(the first left child) is able to receive the information and print it; however the second pipe(the first right child) times out before receiving any information. I'm not sure why, since the first pipe works just fine.

Each child will eventually create their own children, and I can't even begin on this part of the process without having a much better handle on select().

int bit_count(char *passed, int len){
//initialize file descriptors
int fd1[2] = {1, 2};
int fd2[2] = {3, 4};

fd_set read_set;
fd_set write_set;

//set timeval structure for timeout
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;

FD_ZERO(&read_set);             //clear the set
FD_SET(fd1[0], &read_set);      //add first file descriptor to set
FD_SET(fd2[0], &read_set);      //add second file descriptor to set

//open the pipes
pipe(fd1);
pipe(fd2);

//fork a child process
pid_t kid = fork();
if(kid == -1) printf("forking failed.");

if (kid == 0){  //first child process
    int status = 1;
    while(status){
        int retval = select(fd1[0]+1, &read_set, NULL, NULL, &tv);

        switch(retval) {
                case -1:
                        printf("Select Error.\n");
                        exit (-1);
                        status = 0;
                        break;

                case 0:
                        printf("Timeout...");
                        status = 0;
                        break;

                default:
                        if (FD_ISSET(fd1[0], &read_set)) {
                            char *lstring = malloc(sizeof(char)*(len/2));
                            read(fd1[0], lstring, len);
                            printf("Child Left: %s\n", lstring);
                            close(fd1);
                            //execl("child.c", parent);
                            status = 0;
                            }
                    }
    }
}

else{       //parent process
    //fork a second child process
    pid_t kid2 = fork();

    if (kid2 == 0) {    //second child process
        int status = 1;
        while(status){
            int retval = select(fd2[0]+1, &read_set, NULL, NULL, &tv);

            switch(retval) {
            case -1:
                    printf("Select Error.\n");
                    exit (-1);
                    status = 0;
                    break;

            case 0:
                    printf("Timeout...");
                    status = 0;
                    break;

            default:
                    if (FD_ISSET(fd2[0], &read_set)) {
                        char *rstring = malloc(sizeof(char)*((len/2)+(len%2)));
                        read(fd2[0], rstring, len);
                        printf("Child Right: %s\n", rstring);
                            //execl("child.c", parent);
                        status = 0;
                    }
            }
    }
    }

    else{
        int status;
        //create character arrays for
        printf("\n\nParent Original String: %s\n", passed);
        printf("Measured Length: %d\n", len);
        int left = (len/2);
        int right =(len/2)+(len % 2);
        char *lstring = malloc(sizeof(char)*(left+1));
        char *rstring = malloc(sizeof(char)*(right+1));
        memcpy(lstring, passed, left);
        lstring[left] = '\0';
        memcpy(rstring, passed+left, right);
        rstring[right] = '\0';
        printf("Parent Left: %s\n", lstring);
        printf("Parent Right: %s\n", rstring);
        write(fd1[1], lstring, sizeof(char)*(left+1));
        write(fd2[1], rstring, sizeof(char)*(right+1));
        waitpid(kid, &status, NULL);
        waitpid(kid2, &status, NULL);
        }
    return 0;
}
return 0;
}
War es hilfreich?

Lösung

If you read a reference page, you will see that

Upon successful completion, the pselect() or select() function shall modify the objects pointed to by the readfds, writefds, and errorfds arguments

So you have to set the descriptor sets every iteration through the loop before calling select.

Also note that the timeout structure may be modified as well.

You should also use the largerst descriptor (plus one) as the first argument. If fd2[0] is larger than fd1[0] then the call will not work as expected.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top