简体   繁体   English

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

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

I'm trying to establish an inter process communication on Linux using named pipes.我正在尝试使用命名管道在 Linux 上建立进程间通信。 At first glance my code seems to work, but I noticed that sometimes data written to the pipe by the "main" process is read twice by the "child" process (in fact it's two separate programs).乍一看,我的代码似乎有效,但我注意到有时“主”进程写入管道的数据会被“子”进程读取两次(实际上它是两个单独的程序)。

Program 1 (write only, starts first) is a legacy program.程序 1(只写,先启动)是一个遗留程序。 The below code is implemented in a onclick-function for a button on a GUI.以下代码是在 GUI 上按钮的 onclick 函数中实现的。 When I press the button the data string shall be sent via pipe to another program.当我按下按钮时,数据字符串将通过管道发送到另一个程序。 Code:代码:

main.h主文件

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

main()主要的()

::mkfifo(FSCpipe, 0666);

OnClick-Function 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++;

Program 2 (only read, starts second) is started in a new terminal.程序 2(仅读取,第二个启动)在新终端中启动。 Code:代码:

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

Sometimes I noticed a strange behaviour, feeling like there is more data read then written.有时我注意到一种奇怪的行为,感觉读取的数据多于写入的数据。 So I implemented independent counter in both programs.所以我在两个程序中都实现了独立的计数器。 When I press the button in program 1, the data is send via the pipe and the counter increments.当我按下程序 1 中的按钮时,数据通过管道发送并且计数器递增。 When program 2 receives and outputs the data in the terminal, its counter is also incremented.当程序2在终端接收和输出数据时,它的计数器也增加。 After some clicks on the button in program 1, I can see a higher counter value in program 2, indicating that it reads more often then program 1 writes.单击程序 1 中的按钮后,我可以看到程序 2 中的计数器值更高,表明它读取的频率高于程序 1 的写入频率。 Why is that ?这是为什么 ?

Apart from that, the data string should contain special characters encoded in UTF-8, like this:除此之外,数据字符串应包含以 UTF-8 编码的特殊字符,如下所示:

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

How should I convert the string to send it correctly via pipe?我应该如何转换字符串以通过管道正确发送它?

Thank you for helping me!感谢你们对我的帮助!

I found some helpful information here , stating:我在这里找到了一些有用的信息,说明:

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

I took out fd = ::open(...);我拿出fd = ::open(...); and ::close(fd);::close(fd); from my onclick-function in program 1 and put them into the mainwindow-constructor and the mainwindow-close-function respectively.从我在程序 1 中的 onclick-function 并将它们分别放入 mainwindow-constructor 和 mainwindow-close-function 中。 So the write end is always opened and program 2 works as intended.所以写端总是打开的,程序 2 按预期工作。

Thank you all for your help.谢谢大家的帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM