读取 fifo:为什么它阻塞然后非阻塞

read fifo: why is it blocking then non-blocking

我正在使用 FIFO 让两个进程进行通信。

//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);


服务器将首先阻塞在那里等待 fifoName 中的某些消息。当一些消息到来时(客户端被执行),服务器读取它们然后循环结束。

我现在很困惑。因为我不明白为什么服务器第一次调用 read 并且它在那里阻塞,而当它再次调用 read 并且它不再阻塞时。

我打印 read 的 return 值,我在收到第一条消息后得到 0。

我需要的是让read每次都阻塞,这样服务器就可以在某个客户端发送消息时立即接收到任何消息。

您可以简单地重试读取。例如

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);

你得到 0 作为指示器,没有更多数据剩余,并且随着管道的另一侧关闭,将没有更多数据。

我想您希望服务器保持稳定并处理多个客户端,甚至可能同时处理多个客户端。

管道根本不适合此目的。您想改用 unix 套接字

最后,像这样循环:

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

从根本上说是错误的。很容易因为信号的到来导致读取出错。

另请注意,您对缓冲区大小重复“100”而不是例如“100”违反了 DRY。使用 sizeof(msg).