上周我发布了类似的question,这篇文章反映了我的试验和我现在面临的问题。Python - 如何在subprocess.Popen中从PIPE读取非阻塞?
通过Popen调用的程序是一个命令行程序。我使用一个线程从队列中读取一个项目并将其发送到stdin,并从stdout获取响应。但它在proc.stdout.read()
中挂起。我确实看到它在上周五的预期输出中正常工作,然后当我今天做了一些更改时,它会挂起。我所做的更改将使用readlines()
取代read()
并使用循环来迭代结果。我知道readlines()
可能会阻止,但是当我将代码翻转到上周五的read()
时,它也会阻止。我现在完全迷失了。任何可能的原因?
下面是代码从队列中取得一个句子,其提供给Java程序得到回应:
''' below is the code for worker thread. '''
def readQueue(proc, queue):
print 'enter queueThread.\n'
global notEmpty
notEmpty = True
while notEmpty:
try:
sen = queue.get()
proc.stdin.write(sen.strip())
res = proc.stdout.read()
print res.strip(), ' ', sen
queue.task_done()
except Empty:
break
print 'leave queueThread.'
下面的主线是从文件中读取每一行,并把它放在一个队列中的工作线程逐项处理:
def testSubprocess():
ee = open('sentences.txt', 'r')
#ff = open('result.txt', 'w') # print it to stdout first before really write to a file.
lines = ee.readlines()
cmd = ['java',
'-cp', 'someUsefulTools.jar',
'className',
'-stdin',] # take input from stdin
proc = Popen(cmd, stdout=PIPE, stdin=PIPE, stderr=PIPE, bufsize=-1, universal_newlines=True)
q = Queue()
for sen in lines:
q.put(sen.strip())
readThread = Thread(target=readQueue, args=(proc, q))
readThread.daemon = True
readThread.start()
print 'Main thread is waiting...\n'
q.join()
global notEmpty; notEmpty = False
print 'Done!'
道歉,如果我误解你的代码,这是不行的,但是我发现我可以堵塞这种方式停止管道。 (我没有很多python线程的经验)在定义“proc”之后,添加这个:“fcntl.fcntl(proc,fcntl.F_SETFL,os.O_NONBLOCK)”如果proc被定义为类型“pipe “这应该阻止它阻止。你可能需要导入fcntl。 – Aphire
@Aphire不知道我是否正确,它似乎“fcntl”用于linux/unix环境,对吧? (我的工作环境是windows) –
想象一下,你给java程序发送一个句子:你怎么知道什么时候停止读取响应:它是否总是* 10个字节或者它总是*单行还是你想要读直到EOF即,每个进程只能回答**单个**问题? – jfs