【问题标题】:Reading continuous data from a named pipe从命名管道读取连续数据
【发布时间】:2015-04-11 22:55:05
【问题描述】:

我一直在尝试从命名管道中读取连续数据。但是由于某种原因,如果我不延迟,接收器将停止读取,并且在几个样本后只显示一个空白屏幕。

我需要发送可能在毫秒内发生变化的连续数据,这就是为什么延迟不起作用的原因。我正在尝试首先使用 while 循环来模拟它(真正的脚本将读取财务数据)。这是我的第一次尝试:

这是发件人,一个python脚本:

import os
import time

try:
    os.remove("/tmp/pipe7")    # delete
except:
    print "Pipe already exists"
os.mkfifo("/tmp/pipe7")    # Create pipe
x = 0
while True:
    x = time.time()
    pipe = open("/tmp/pipe7", "w")
    line = str(x) + "\r\n\0"
    pipe.write(line)
    pipe.close()

    #time.sleep(1)


os.remove("/tmp/pipe7")    # delete

这是 C/C++ 中的接收器:

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <iostream>

#include <sys/stat.h>

#define MAX_BUF 1024


using namespace std;

int main()
{

    while(1){

        char buf[MAX_BUF];
        memset (buf, 0, sizeof(buf)); //Clearing the message buffer
        int fd = open("/tmp/pipe7", O_RDONLY);  // Open the pipe
        read(fd, buf, MAX_BUF);                         // Read the message - unblock the writing process
        cout << buf << endl;
        close(fd);                                 // Close the pipe

    }
    return 0;
}

我的方法有什么问题?使用管道在两个程序之间持续通信的最佳方式是什么?

【问题讨论】:

  • 我想知道为什么您每次读/写一行时都觉得需要打开和关闭管道?也许你错过了文件对象的flush 方法?
  • @SylvainLeroux:这肯定是问题所在,因为管道逻辑绑定到可用的读取器和写入器。
  • 我尝试不每次都关闭管道,但似乎仍然没有解决问题。我对管道或套接字编程没有太多经验。所以我很难找出问题所在。

标签: python c++ ipc named-pipes fifo


【解决方案1】:

首先,您不需要为每个 I/O 操作打开/关闭管道。 最终你可能需要在每次写入后刷新输出。

然后,当您输出基于行的文本数据时,您不能真正依靠固定宽度的读数来取回数据。鉴于你的例子,我会简单地读入一个字符串——istream 应该读到下一个空白(这里是\n\r

所有这些都导致了一些类似的东西(未经测试——当心错别字!):

with open("/tmp/pipe7", "w") as pipe:
    while True:
        x = time.time()
        line = str(x) + "\r\n"
        pipe.write(line)
        pipe.flush()
        # in real code, should somehow break the loop at some point

std::ifstream  pipe("/tmp/pipe7");  // Open the pipe
while(1){
    std::string istr;

    pipe >> istr;        
    cout << istr << endl;
    # In real code, should somehow break the loop at some point
}

close(fd);

operator &gt;&gt; 被重载以从 istream 中读取字符串。在这种情况下,它将从流中提取字符并在遇到空白字符或遇到流结尾时立即停止。从广义上讲,这允许“逐字”读回输入。

【讨论】:

  • 太棒了,这很好用。您能否详细说明如何将管道中的数据读入字符串? read() 方法不接受字符串对吧?
  • Nvm 我刚刚看到您使用 ifstream 进行的编辑。非常感谢,这太棒了!!谢谢。
  • 再问一个问题。在这种情况下使用 istream 不会影响性能,对吧?打印到屏幕时,我发现数据变慢了很多。
  • @Luis 只是随机猜测,也许“减速”与缓冲区有关。尝试disable ifstream buffering
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2020-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多