目前我通过蓝牙从设备获取MAC地址,并且我将这些mac地址一次传递给一个调用子进程并将输出分配给变量的方法。使用该变量,我运行一些过滤函数,以从子进程中调用的命令中获取值。然后,如果它从输出中找到它,则返回该值。
我想要做的是立即将所有mac地址传递给方法并一次运行它们。如何在进程完成时捕获每个进程的输出并运行我的过滤脚本,同时通知我进程是否失败或错误。
以下是一次处理一个mac的当前方法。让我们假设我正在传递一个mac地址列表。
def getchan(mac):
a = subprocess.Popen(["sdptool", "search","--bdaddr", mac, "OPUSH"], stdout = subprocess.PIPE).communicate()[0].split()[2:]
if a==[]:
print "ERROR"
return "ERROR"
else:
count = 0
for item in a:
if item == "Channel:":
return a[count + 1]
count += 1
return "Could not find the OPUSH channel"
应该看起来像
def getchan(macs):
processes = set()
for mac in macs:
processes.add(subprocess.Popen(["sdptool", "search","--bdaddr", mac, "OPUSH"], stdout = subprocess.PIPE).communicate()[0].split()[2:])
#this is where I need the help
谢谢你看看。任何对子流程的帮助或澄清将不胜感激。
答案 0 :(得分:1)
import select
import subprocess
def in_parallel(processes):
pipes = {p.stdout.fileno(): (i, p.stdout) for i, p in enumerate(processes)}
poller = select.poll()
for fd, pipe in pipes.iteritems():
poller.register(fd, select.POLLIN)
outputs = [''] * len(processes)
while pipes:
active = poller.poll()
for fd, event in active:
idx, pipe = pipes[fd]
o = pipe.read()
if o:
outputs[idx] += o
else:
poller.unregister(fd)
pipe.close()
del pipes[fd]
for p in processes:
p.wait()
return outputs
args = ['a', 'b', 'c']
processes = [subprocess.Popen(['sleep 5; echo ' + arg], stdout=subprocess.PIPE, shell=True) for arg in args]
outputs = in_parallel(processes)
print outputs
$ time python test.py
['a\n', 'b\n', 'c\n']
real 0m5.042s
user 0m0.016s
sys 0m0.016s
答案 1 :(得分:0)
以可移植的方式并行获取子进程输出的最简单方法是使用线程:
from multiprocessing.dummy import Pool # use threads
from subprocess import check_output
def getchan_mp(mac):
try:
output = check_output(["sdptool", "search","--bdaddr", mac, "OPUSH"])
result = parse(output)
return result, mac, None
except Exception as err:
return None, mac, err
results = Pool(processes=len(macs)).map(getchan_mp, macs)
failed_macs = [mac for result, mac, error in results if error is not None]