如何实现subprocess子线程信息实时回传

xiaokang007 2010-08-03 10:32:12
要求:运行子线程之后,子线程如果有输出信息,就立刻传回主线程。
不知主线程和子线程要做怎样的设置,请大伙帮忙。
以下是我的测试代码,只能实现在子线程结束之后,才能回传stdout信息。


import subprocess

def main():
process1 = subprocess.Popen("python sub.py", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
print process1.communicate()[0]

if __name__ == '__main__':
main()



以下是上面子线程要调用的代码
sub.py
import subprocess
def main():
process1 = subprocess.Popen("ping 128.101.1.4 -n 1", shell=True, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
process2 = subprocess.Popen("ping 128.101.1.4 -n 3", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
process3 = subprocess.Popen("ping 128.101.1.4 -n 6", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)

while 1:
time.sleep(1)
ret1 = subprocess.Popen.poll(process1)
ret2 = subprocess.Popen.poll(process2)
if ret1 is None:
print process1.pid, " running"
else:
print process2.pid, " Termined"

if ret2 is None:
print process2.pid, " running"
else:
print process2.pid
win32api.TerminateProcess(int(process3._handle), -1)

break

#if __name__ == '__main__':
main()
...全文
1579 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
ponder008 2011-06-29
  • 打赏
  • 举报
回复
谢谢,楼上的各位达人,正找这问题呢
xiaokang007 2010-11-10
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 zhoubols 的回复:]
引用 2 楼 angel_su 的回复:
communicate()是要等进程退出才返回,试试一行行读取
Python code
import subprocess
import time

p = subprocess.Popen('ping 127.0.0.1 -n 10', stdout=subprocess.PIPE)
while p.poll() == None:
pri……
[/Quote]

谢谢分享
劲草 2010-11-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 angel_su 的回复:]
communicate()是要等进程退出才返回,试试一行行读取
Python code
import subprocess
import time

p = subprocess.Popen('ping 127.0.0.1 -n 10', stdout=subprocess.PIPE)
while p.poll() == None:
print p.stdout.readline()
……
[/Quote]
也可以这么写,
import subprocess
sp = subprocess.Popen('ping 127.0.0.1 -n 100', stdout=subprocess.PIPE)
while True:
line = sp.stdout.readline()
if not line:break
print line
if sp.wait() == 0:
print 'sub process execute ok'
matlab2000 2010-10-31
  • 打赏
  • 举报
回复 1
请参考最新的google上的subprocess代码。以前的实现中读是阻塞的,直到EOF才返回。新代码中用了select,可以不阻塞。
xiaokang007 2010-08-03
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 notax 的回复:]
看看用unbuffer行不?



Python code

import subprocess

def main():
process1 = subprocess.Popen("python -u sub.py", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT) # mo……
[/Quote]


没有用 ,加入 -u 参数也是在子线程结束后,输出子线程中的print信息
谢谢 notax
angel_su 2010-08-03
  • 打赏
  • 举报
回复
communicate()是要等进程退出才返回,试试一行行读取
import subprocess
import time

p = subprocess.Popen('ping 127.0.0.1 -n 10', stdout=subprocess.PIPE)
while p.poll() == None:
print p.stdout.readline()
time.sleep(1)
print p.stdout.read()
print 'returen code:', p.returncode


因为知道ping会一行行输出所以上面readline可以正常,倘若读不到行就会发生阻塞,非阻塞的看看下面文章...
http://www.python.org/dev/peps/pep-3145/
notax 2010-08-03
  • 打赏
  • 举报
回复
看看用unbuffer行不?



import subprocess

def main():
process1 = subprocess.Popen("python -u sub.py", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT) # modify to python -u
print process1.communicate()[0]

if __name__ == '__main__':
main()

notax 2010-08-03
  • 打赏
  • 举报
回复
哦,学习了, "communicate()是要等__程退出才返回"

I was blind but now I can see.

http://docs.python.org/library/subprocess.html#subprocess.Popen.communicate

Popen.communicate(input=None)¶
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optional input argument should be a string to be sent to the child process, or None, if no data should be sent to the child.




试了一下,也行


import subprocess

def main():
process1 = subprocess.Popen("python -u sub.py", shell=False, stdout = subprocess.PIPE, stderr=subprocess.STDOUT)
#print process1.communicate()[0]

while True:
line = process1.stdout.readline()
if not line:
break
print line

if __name__ == '__main__':
main()

xiaokang007 2010-08-03
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 angel_su 的回复:]
communicate()是要等进程退出才返回,试试一行行读取

Python code
import subprocess
import time

p = subprocess.Popen('ping 127.0.0.1 -n 10', stdout=subprocess.PIPE)
while p.poll() == None:
print p.stdout.read……
[/Quote]


感谢 angel_su 提供的方法, 测试可以实时返回子线程信息。

关于:
因为知道ping会一行行输出所以上面readline可以正常,倘若读不到行就会发生阻塞
可以做一些处理, 假如读不到(测试发现返回值是None),可以判断不为None在返回给主线程。
xiaokang007 2010-08-03
  • 打赏
  • 举报
回复
新发现:
就我的测试程序来调试看,在主线程程序中 加入 from sub import * ,
就可以实时的 print 出子线程的 信息。

但是在我的实际程序中这个方法也不行,程序中有建立一个继承wxFrame的子类 ,可能是和这个有关系。
而测试程序 只是一个函数,至于为何在 from sub import *之后打印出子线程的实时信息,可能只是因为在同一个控制台执行了这个函数。

37,720

社区成员

发帖
与我相关
我的任务
社区描述
JavaScript,VBScript,AngleScript,ActionScript,Shell,Perl,Ruby,Lua,Tcl,Scala,MaxScript 等脚本语言交流。
社区管理员
  • 脚本语言(Perl/Python)社区
  • IT.BOB
加入社区
  • 近7日
  • 近30日
  • 至今

试试用AI创作助手写篇文章吧