2017-04-26 51 views
0

我使用Python2.7,SPARC ASP解决方案,并从Ubuntu14.04命令运行我的代码线。试图在Python2.7和ASP之间进行双向通信:将命名管道的内容写入文本文件不起作用

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

不幸的是,尽管经过了几天的研究,并询问了有关堆栈溢出的较小问题,尽管本网站上的好人提供了一些非常有用的答案,但我仍然无处可去,我不确定在代码中哪里出现问题所在。所以我会发布我的所有代码,希望有人能够帮助我一劳永逸地解决这个问题。

我的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看看有什么en写。它总是只有?-,没有'是'。我也可以告诉我的python代码只运行一次,因为当我追加到文本文件而不是写入时,每次运行我的代码时只会添加一行。来自ASP求解器的输出应该是?- yes

我怀疑,这个问题是在ASP代码,因为如果在命令行I型> sparc.out代替> fifo(使得输出首先直接放入一个文本文件,而无需通过FIFO去),文本文件包含几十个?- yes重复,这是我所期望的。

我需要弄清楚如何使用fifo而不是将输出写入文本文件,因为不断从文本文件中读取/写入文本文件对于我的代码打算用于应用程序来说太慢了(为一个turtlebot;当我测试机器人上的文本文件版本时,它不断停止并开始,因为它每次从文本文件读取时都会暂停)。

我知道将所有代码转储到帖子中并说'为我修复它!'并不是很好的形式,但我在我的智慧结尾。如果有人能帮助我进行双向沟通,我会非常感激。

回答

1

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

尝试发送您的输入后使用sys.stdout.close(它调用flush),并在循环使用read,直到收到0的返回值,因为有可能会提供目前少于7个字节。

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

相关问题