程序 1 写入 Linux 管道的数据有时会被程序 2 读取两次

Data written on Linux pipe by program 1 is sometimes read twice by program 2

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

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

main.h

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

main()

::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()] = '[=13=]';
::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";

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

谢谢你帮助我!

我找到了一些有用的信息 here,说明:

"If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read(2) from the pipe will see end-of-file (read(2) will return 0)"

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

谢谢大家的帮助。