【问题标题】:Can kdb read from a named pipe?kdb 可以从命名管道中读取吗?
【发布时间】:2012-02-09 15:44:04
【问题描述】:

我希望我做错了什么,但似乎 kdb 无法从命名管道读取数据(至少在 Solaris 上)。它会一直阻塞,直到它们被写入,但随后不返回任何写入的数据。

我可以创建一个文本文件:

$ echo Mary had a little lamb > lamb.txt

kdb 会很高兴地阅读它:

    q) read0 `:/tmp/lamb.txt
enlist "Mary had a little lamb"

我可以创建一个命名管道:

$ mkfifo lamb.pipe

并尝试从中读取:

    q) read0 `:/tmp/lamb.pipe

将导致 kdb 阻塞。写入管道:

$ cat lamb.txt > lamb.pipe

将导致 kdb 返回空列表:

()

kdb 可以从命名管道中读取吗?我应该放弃吗?我不认为这是权限问题(我尝试在我的 mkfifo 命令上设置 -m 777 但这没有任何区别)。

【问题讨论】:

    标签: solaris named-pipes kdb


    【解决方案1】:

    随着版本 kdb+ v3.4 Q 支持命名管道:取决于您是要实现流式算法还是仅从管道中读取,请在 fifo 管道上使用 .Q.fpsread1

    要实现流式传输,您可以执行以下操作:

    q).Q.fps[0N!]`:lamb.pipe
    

    然后$ cat lamb.txt > lamb.pipe

    将打印

    ,"玛丽有一只小羊"

    在您的 q 会话中。可以通过将0N! 替换为适当的函数来实现更有意义的算法。

    要将文件的上下文读入变量,请执行以下操作:

    q)h:hopen`:fifo://lamb.pipe
    q)myText: `char$read1(h)
    q)myText
    

    “玛丽有一只小羊羔\n”

    详细了解命名管道here

    【讨论】:

      【解决方案2】:

      read0 失败时,您可以经常使用system"cat ..." 伪造它。 (我最初是在尝试从 /proc 读取与 read0 不合作的内容时发现的。)

      q)system"cat /tmp/lamb.pipe"
      <blocks until you cat into the pipe in the other window>
      "Mary had a little lamb"
      q)
      

      请注意,调用 system 会产生相当高的开销(如 q 中的此类内容)——它会产生一个完整的 shell 进程来运行您的任何命令

      您也可以直接使用custom C extension 进行操作,可能直接调用read(2)...

      【讨论】:

        【解决方案3】:

        read0 的算法无法查看它在后台执行的操作,但据我所知,它需要一个有限流而不是连续流;所以它会阻塞直到它收到一个EOF信号。

        【讨论】:

        • 我很高兴它被阻止 - 这似乎是连续流的正确行为 - 但它随后返回空列表,而不是写入的数据。这几乎就像它在等待 EOF 然后扔掉在那之前读到的任何东西:s
        • 是的,它很可能会超时。底层算法将提供答案,因此可能值得发送电子邮件至 tech@kx.com 以了解情况。
        【解决方案4】:

        从 v3.4 开始支持从管道流式传输

        详细步骤:

        1. 检查重复的管道文件

          rm -f /path/dataPipeFileName

        2. 创建命名管道

          mkfifo /path/dataPipeFileName

        3. 饲料数据

          q).util.system[$1]; $1=获取数据的命令 > /path/dataPipeFileName &

        4. 使用 kdb .Q.fps 连接管道

          q).Q.fps[0N!]`$":/path/",dataPipeFileName;

        参考: .Q.fps(流式算法) 语法:.Q.fps[x;y] 其中 x 是一元函数,y 是文件路径 .Q.fs 用于管道。 (自 V3.4 起)从管道中读取大小方便的完整“\n”分隔记录块,并将函数应用于每个记录。这使您能够实现流式算法,将大型 CSV 文件转换为磁盘上的 kdb+ 数据库,而无需一次将数据全部保存在内存中。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-01-12
          • 1970-01-01
          • 2014-08-03
          • 2020-07-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多