上週我發佈了類似的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