尝试 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/
我正在使用 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/