【问题标题】:read fifo: why is it blocking then non-blocking读取FIFO:为什么它阻塞然后非阻塞
【发布时间】:2017-04-26 13:41:30
【问题描述】:

我正在使用 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阻塞,以便服务器可以在某些客户端发送消息后立即接收任何消息。

【问题讨论】:

  • 您应该打印出 strerror(errno) 以查看错误是什么。
  • @SumitGemini,我打印 read 的返回值,我得到 0。
  • 所以您希望您的服务器无限运行?连续阅读?
  • @SumitGemini 是的。我每次只需要read 块并等待下一条消息。
  • 为此,您可以简单地重试读取。

标签: c++ c server fifo


【解决方案1】:

你得到 0 作为一个指示,没有更多的数据,并且管道的另一端关闭时将没有更多的数据。

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

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

最后,像这样的循环:

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

根本上是错误的。由于信号到达,读取很容易出错。

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2012-10-31
      • 2016-05-24
      • 2014-11-17
      • 1970-01-01
      • 2015-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多