简体   繁体   中英

Infinite loop while reading from pipe

Can anyone tell me why I have an infinite loop when reading from a pipe? I don't understand what I'm doing wrong. message is the name I defined in main top refer to it. MESSAGE is my struct name. It doesn't even print out test value.

if(manager_pid == 0)
{
    printf("Hello? \n");
    if(close(pipe1[READING]) != 0)
    {
        printf("Error in closing pipe1 \n");
    }
    if(close(pipe2[READING]) != 0)
    {
        printf("Error in closing pipe2 \n");
    }
    if(close(pipe3[WRITING]) != 0)
    {
        printf("Error in closing pipe \n");
    }
}
i = 0;
printf("work please \n");
//test_value = read(pipe3[READING], &boo, sizeof(echo));
//printf("test_value is %d \n", test_value);

while(i < 10)
{
    printf("In while \n");
    //printf("Hello?? \n");
    //test_value = read(pipe3[READING], &boo, sizeof(echo));
    //printf("test_value is %d \n", test_value);
    //printf("Entering infinite loop \n");
    //printf("i is %d \n", i);
    //nbytes = read(pipe3[0], array, 45);
    //printf("nbytes is %d \n", nbytes);
    //log_dat_fp = fopen(argv[2], "a");
    if(read(pipe3[READING], &message, sizeof(struct MESSAGE)) != -1)
    {
        printf("Entering if \n");
        log_dat_fp = fopen(argv[2], "a");
        printf("First if  \n");
        time(&current_time);
        //if(message.owner == 1 && (message.instruction == 'r' || message.instruction == 'R'))
        if(message.instruction == 'r' || message.instruction == 'R')
        {
            if(message.owner == 1)
            {
                printf("message.owner == 1 with r or R \n");
                fprintf(log_dat_fp, "Store Manager at time: %s received message %d %d %c %s", strtok(ctime(&current_time), "\n"), 
                message.owner, getpid(), message.instruction, message.id);
                pclose(log_dat_fp);
            }
            else if(message.owner == 2)
            {
                printf("message.owner == 2 with r or R  \n");
                fprintf(log_dat_fp, "Store Manager at time: %s received message %d %d %c %s", strtok(ctime(&current_time), "\n"), 
                message.owner, getpid(), message.instruction, message.id);
                pclose(log_dat_fp);
            }
            else
            {
                printf("You have junk  \n");
            }
        }
        else if(message.instruction == 'u' || message.instruction == 'U')
        {
            if(message.owner == 1)
            {
                printf("message.owner == 1 with u or U  \n");
                fprintf(log_dat_fp, "Store Manager at time: %s received message %d %d %c %s %d", strtok(ctime(&current_time), "\n"), 
                message.owner, getpid(), message.instruction, message.id, message.value);
                pclose(log_dat_fp);
            }
            else if(message.owner == 2)
            {
                printf("message.owner == 2 with u or U  \n");
                fprintf(log_dat_fp, "Store Manager at time: %s received message %d %d %c %s %d", strtok(ctime(&current_time), "\n"), 
                message.owner, getpid(), message.instruction, message.id, message.value);
                pclose(log_dat_fp);
            }
            else
            {
                printf("You have junk  \n");
            }
        }
        else
        {
            printf("manager can't read from pipe\n");
            exit(1);
        } // read no good
        if(message.instruction == 'r' || message.instruction == 'R')
        {
            if(message.owner == 1)
            {
                for(i = 0; i < 200; i++)
                {
                    if(strcmp(storage, table[i].id) == 0)
                    {
                        match_flag = 1;
                        value = table[i].value;
                    }
                }
                if(match_flag == 1)
                {
                    message.value = value;
                    message.owner = 0;
                    if(write(pipe1[WRITING], &message, sizeof(struct MESSAGE)) == sizeof(struct MESSAGE))
                    {
                        log_dat_fp = fopen(argv[2], "a");
                        time(&current_time);
                        fprintf(log_dat_fp, "Store Manager at time: %s sent message: %c %d %s %d\n", strtok(ctime(&current_time), "\n"), 
                        message.instruction, message.owner, message.id, message.value);
                        fclose(log_dat_fp);
                    }
                    else
                    {
                        printf("error returning message to process 1");
                        exit(1);
                    }
                }
                else
                    message.owner = 1;
                    if(write(pipe1[WRITING], &message, sizeof(struct MESSAGE)) == sizeof(struct MESSAGE))
                    {
                        log_dat_fp = fopen(argv[2], "a");
                        time(&current_time);
                        fprintf(log_dat_fp, "Store Manager at time: %s sent message: %c %d %s \n", strtok(ctime(&current_time), "\n"), 
                        message.instruction, message.owner, message.id);
                        fclose(log_dat_fp);
                    }

            }
            else if(message.owner == 2)
            {
                printf("message.owner == 2 with u or U  \n");
                fprintf(log_dat_fp, "Store Manager at time: %s received message %d %d %c %s %d", strtok(ctime(&current_time), "\n"), 
                message.owner, getpid(), message.instruction, message.id, message.value);
                pclose(log_dat_fp);
            }
            else
            {
                printf("You have junk  \n");
            }

        }
    }
    else
    {
        printf("manager had pipe issues.\n");
        exit(1);
    }// read no good
    i++;
    //log_dat_fp = fopen(argv[2], "a");
    printf("Each pass  \n");
}

The POSIX read() function returns 0 on EOF, not -1. Since you test for the wrong condition, you get an infinite loop.

Note that the description says:

When attempting to read from an empty pipe or FIFO:

  • If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file.

  • If some process has the pipe open for writing and O_NONBLOCK is set, read() shall return -1 and set errno to [EAGAIN] .

  • If some process has the pipe open for writing and O_NONBLOCK is clear, read() shall block the calling thread until some data is written or the pipe is closed by all processes that had the pipe open for writing.

Reading zero bytes because there are no bytes to read is success. That is how EOF is indicated by read() , whether it is on a file or any other device type. Terminals are a special case; they may return 0 bytes after you type (on Unix) control-D , and then a retry may return extra data typed after that. Once upon a long time ago, tape drives were somewhat similar. But when read() returns 0, there is (for the time being) no more data to read. For a pipe, that means all writers closed their write file descriptor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM