尝试 Python2.7 和 ASP 之间的双向通信:将命名管道的内容写入文本文件不起作用

Attempting two-way communication between Python2.7 and ASP: writing contents of named pipe to a text file not working

我正在使用 Python2.7,SPARC ASP 求解器,并且正在 运行 从 Ubuntu14.04 命令行运行我的代码。

我正在尝试在我的 Python 代码和我的 ASP(答案集编程)代码之间建立双向通信。为此,我将查询从 python 发送到 ASP,将 ASP 响应放入 fifo 管道,并在 python 代码中读取 fifo 的内容一个字符串,然后将该字符串写入一个文本文件(这样我就可以检查文本文件,看看我是否得到了我期望的输出)。但是出现了两个问题:只有部分预期响应出现在文本文件中,而不是全部,尽管我的 python 代码处于无限 while 循环中,但它似乎只是 运行ning一次。出了什么问题?

不幸的是,尽管经过几天的研究并提出了一些关于堆栈溢出的小问题,尽管本网站上的好心人提供了一些非常有用的答案,但我仍然一无所获,而且我不确定我的代码在哪里问题所在。所以我将post我所有的代码,希望有人能帮助我一劳永逸地解决这个问题。

我的python代码:

import sys
import os

while True:
    # communicate with ASP code
    try:
        sys.stdout.write('moveForward(turtlebot)\n')
    except KeyboardInterrupt:
        sys.stdout.write('moveForward(turtlebot)\n')
        sys.exit()

    # read back the output of the ASP code - should be '?- yes'
    try:
        fifo = os.open('fifo', os.O_RDONLY)
        string = os.read(fifo, 7)
        os.close(fifo)
    except KeyboardInterrupt:
        fifo = os.open('fifo', os.O_RDONLY)
        string = os.read(fifo, 7)
        os.close(fifo)
        sys.exit()  

    # write the latest output to the text file
    try:
        myfile = open("afile.txt", "w")
        myfile.write(string)
        myfile.close()
    except KeyboardInterrupt:
        myfile = open("afile.txt", "w")
        myfile.write(string)
        myfile.close()
        sys.exit()

我的ASP代码:

sorts
#robot = {turtlebot}.

predicates
moveForward(#robot).

rules
moveForward(turtlebot).

我如何从命令行 运行 我的代码:

mkfifo fifo
python test.py | java -jar sparc.jar aspfile.sp > fifo

发生了什么:
在 运行 完成我的代码后,我检查 afile.txt 看看写了什么。它始终只是 ?-,没有 'yes'。我还可以看出我的 python 代码只有 运行ning 一次,因为当我附加到文本文件而不是写入时,每次我 运行 我的代码只添加一行。 ASP 求解器 的输出应该?- yes.

我怀疑问题出在 ASP 代码中,因为如果在命令行中我输入 > sparc.out 而不是 > fifo (这样输出会直接放入text file without going through the fifo first), 文本文件包含数十次重复 ?- yes,这正是我所期望的。

我需要弄清楚如何使用 fifo 而不是仅仅将输出写入文本文件,因为不断读取/写入文本文件对于我的代码所针对的应用程序(创建行动计划)来说太慢了对于 turtlebot;当我在机器人上测试文本文件版本时,它不断停止和启动,因为它每次从文本文件读取时都会暂停)。

我知道将我的所有代码都转储到 post 并说 'fix it for me!' 不是很好的形式,但我束手无策。如果有人可以帮助我进行双向通信,我将不胜感激。

在我看来像是一个缓冲问题。使用 write 并不意味着其他进程已完全收到您的消息。这只是意味着它们已被复制到您的内部写入缓冲区。这个缓冲区通常有 4k 大小,如果它没有被完全填满,则不会向另一端发送任何内容。同样,当您 read 时,您不能期望 7 个字节立即可用,因为另一端可能发送的不够。 SPARC 很可能只是打印 '?- ',您会立即收到,然后等待您尚未发送的输入。您可以使用 flush 强制发送写入缓冲区。您可能还需要 close stdout(隐式调用 flush 以发送非空写入缓冲区),因为 SPARC 可能会在开始计算之前等待 EOF。

尝试在发送输入后使用 sys.stdout.close(调用 flush),并在循环中使用 read,直到收到 0 作为 return 值,因为目前可用的字节可能少于 7 个。

这也是对 stdio 缓冲的一个很好的概述:http://www.pixelbeat.org/programming/stdio_buffering/