首页 > 解决方案 > 程序 1 在 Linux 管道上写入的数据有时会被程序 2 读取两次

问题描述

我正在尝试使用命名管道在 Linux 上建立进程间通信。乍一看我的代码似乎可以工作,但我注意到有时由“主”进程写入管道的数据被“子”进程读取两次(实际上它是两个独立的程序)。

程序 1(只写,先启动)是一个遗留程序。下面的代码在 GUI 上的按钮的 onclick 函数中实现。当我按下按钮时,数据字符串将通过管道发送到另一个程序。代码:

主文件

const char * FSCpipe = "/tmp/fscpipe";
int counter = 1;

主要的()

::mkfifo(FSCpipe, 0666);

OnClick 功能

QString data = "179.45";
int fd;
char msg[10];

fd = ::open(FSCpipe, O_WRONLY | O_NONBLOCK);
for(int i = 0; i < data.length(); i++) {
    msg[i] = data.at(i).toLatin1();
}
msg[data.length()] = '\0';
::write(fd, msg, strlen(msg)+1);
::close(fd);
qDebug() << QString("Counter: %1").arg(counter);
counter++;

程序 2(只读,第二个启动)在新终端中启动。代码:

int main(int argc, char **argv)
{    
   int fd;
   const char * FSCpipe = "/tmp/fscpipe";
   char data[10];
   size_t nbytes;
   nbytes = sizeof(data);
   while(1) {
      fd = open(FSCpipe, O_RDONLY);
      ssize_t bytesread = read(fd, data, nbytes);
      printf("received: %s\n", data);
      close(fd);
      printf("Counter: %d ", counter);
      printf("chars: %d\n", bytesread);
      counter++;
   }
   return(0);
}

有时我注意到一种奇怪的行为,感觉读取的数据多于写入的数据。所以我在两个程序中都实现了独立的计数器。当我按下程序 1 中的按钮时,数据通过管道发送并且计数器递增。当程序 2 在终端接收和输出数据时,它的计数器也会递增。在程序 1 中单击一些按钮后,我可以看到程序 2 中的计数器值更高,这表明它读取的频率高于程序 1 的写入频率。这是为什么 ?

除此之外,数据字符串应包含以 UTF-8 编码的特殊字符,如下所示:

QString data = "197,45 \xc2\xb5m";

我应该如何转换字符串以通过管道正确发送?

感谢你们对我的帮助!

标签: c++clinuxpipe

解决方案


我在这里找到了一些有用的信息,说明:

“如果引用管道写入端的所有文件描述符都已关闭,则尝试从管道读取(2)将看到文件结束(读取(2)将返回 0)”

我从程序 1 中的 onclick-function 中取出fd = ::open(...);::close(fd);分别放入 mainwindow-constructor 和 mainwindow-close-function。所以写端总是打开,程序 2 按预期工作。

谢谢大家的帮助。


推荐阅读