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

时间:2016-12-11 16:08:42

标签: c++ c server fifo

我正在使用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的返回值,收到第一条消息后我得到0。

我需要的是每次都使read阻止,以便服务器可以在某个客户端发送消息后立即收到任何消息。

2 个答案:

答案 0 :(得分:1)

你得到0作为一个指标,没有剩下的数据,并且随着管道的另一侧关闭,将不再有数据。

我认为你希望服务器能够坚持并处理多个客户端,甚至可能在同一时间。

管道从根本上说不适用于此目的。您想要使用 unix套接字

最后,像这样的循环:

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

从根本上说是错误的。由于信号到达,很容易从读取中获得错误。

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

答案 1 :(得分:0)

您只需重试读取即可。例如

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