简体   繁体   中英

read fifo: why is it blocking then non-blocking

I'm using FIFO to make two processes communicate.

//client:
const char * msg = "Hello, I'm cleint1.";
const char * fifoName = "../server/fifo.tmp";
int fd = open(fifoName, O_WRONLY);
write(fd, msg, strlen(msg) + 1);
close(fd);



//server:
char msg[100];
const char * fifoName = "fifo.tmp";
mkfifo(fifoName, 0666);
int fd = open(fifoName, O_RDONLY);
while(read(fd, msg, 100) > 0)
{
    std::cout<<"msg received: "<<msg<<std::endl;
}
close(fd);
unlink(fifoName);


The server will first block there to wait for some messages in fifoName . When some messages are coming (the client is executed), the server reads them and then the loop will finish.

I'm confused now. Because I can't figure out why the first time that the server calls read and it blocks there whereas when it calls read again and it doesn't block anymore.

I print the return value of read and I get 0 after receiving the first message.

What I need is to make the read blocking each time so that the server can receive any message as soon as some client sends messages.

You got 0 as an indicator there is no more data left and there will be no more data as the other side of the pipe got closed.

I presume you want the server to stick around and handle multiple clients, possibly even at the same time.

Pipes are fundamentally unsuitable for this purpose. You want to use unix sockets instead.

Finally, loops like this one:

while(read(fd, msg, 100) > 0)
{
    std::cout<<"msg received: "<<msg<<std::endl;
}

are fundamentally wrong. it is very easy to get an error from read due to signal arrival.

Also note you violate DRY by repeating the '100' for the buffer size as opposed to eg using sizeof(msg).

you can simply retry the read. For example

int iResult;

do
{
    iResult = read(fd, buffer, size);
    if (0 == iResult)
    {
           // Skip to the end of the do loop
            continue;
    }
        // Handle real errors
} while (!condition);

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