0

目前,我正在通过蓝牙从设备获取 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

谢谢你看看。任何对子流程的帮助或澄清将不胜感激。

4

2 回答 2

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
于 2013-08-16T03:39:30.777 回答
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]
于 2013-08-16T08:29:12.697 回答