[英]Why does Popen.stdout contain only part of output?
我在python中使用子進程模塊同時運行兩個進程:
p_topic = subprocess.Popen(['rostopic','echo','/msg/address'], stdout=PIPE)
p_play = subprocess.Popen(['rosbag','play',bagfile_path])
這些是ROS進程: p_topic
偵聽要播放的.bag
文件,並將該.bag
文件中的某些信息輸出到stdout流; 我想使用p_topic.stdout
對象(其行為作為文件)訪問此輸出。
但是,我發現的事情是p_topic.stdout
對象只包含它應該具有的第一個〜1/3的輸出行 - 也就是說,與手動運行這兩個命令相比,它們同時在兩個shell中並排。
我已經嘗試等待很多秒才能完成輸出,但這並沒有改變任何東西,它每次與p_topic.stdout
捕獲的線的比例大致相同。 任何關於這可能是什么的提示將不勝感激!
編輯:
這是閱讀代碼:
#wait for playing to stop
while p_play.poll() == None:
time.sleep(.1)
time.sleep(X)#wait for some time for the p_topic to finish
p_topic.terminate()
output=[]
for line in p_topic.stdout:
output.append(line)
請注意,time.sleep(X)中的值X沒有任何區別
默認情況下,當進程的stdout
未連接到終端時,輸出將被塊緩沖。 連接到終端時,它的線路緩沖。 你希望得到完整的行,但你不能除非rostopic
unbuffers或明確行緩沖它的stdout
(如果它是一個C程序,你可以使用setvbuf
使這個自動化)。
另一個(可能是重疊的)可能性是管道緩沖區本身正在填充(管道緩沖區通常相當小),並且因為你永遠不會消耗它, rostopic
填充管道緩沖區然后無限期地阻塞直到你殺死它,只留下什么設法當你閱讀過程的stdout
時,適合要排干的管道。 在這種情況下,您需要生成一個線程以保持管道從Python中耗盡,或者讓主線程使用select
模塊組件來監視和排空管道(與輪詢其他過程混合)。 該線程通常更容易,但您需要小心避免線程安全問題。
是否值得嘗試流程溝通/等待? 而不是睡覺,這會解決你的問題嗎?
我有這個用於一般目的所以不確定你是否可以把它改成你需要的東西?
executable_Params = "{0} {1} {2} {3} {4}".format(my_Binary,
arg1,
arg2,
arg3,
arg4)
# execute the process
process = subprocess.Popen(shlex.split(executable_Params),
shell=False,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE)
stdout, stderr = process.communicate()
ret_code = process.wait()
if ret_code == 0:
return 0
else:
#get the correct message from my enum method
error_msg = Process_Error_Codes(ret_code).name
raise subprocess.CalledProcessError(returncode=ret_code,
cmd=executable_Params)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.