多处理简单功能不起作用,但原因何在

时间:2017-08-24 13:29:39

标签: python

我正在尝试多处理系统命令,但无法使用简单的程序。函数runit(cmd)工作正常但是......

row_user.setDuplicateParentStateEnabled(true);
row_user.setClickable(true);

输出:

#!/usr/bin/python3
from subprocess import call, run, PIPE,Popen
from multiprocessing import Pool
import os
pool = Pool()

def runit(cmd):
    proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
    return proc.stdout.read()

#print(runit('ls -l'))

it = []
for i in range(1,3):
    it.append('ls -l')

results = pool.map(runit, it)

然后它以某种方式等待并且什么都不做,当我按下Ctrl + C几次时它会吐出来:

Process ForkPoolWorker-1:
Process ForkPoolWorker-2:
Traceback (most recent call last):
Traceback (most recent call last):
  File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
    self.run()
  File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 108, in worker
    task = get()
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 345, in get
    return ForkingPickler.loads(res)
AttributeError: Can't get attribute 'runit' on <module '__main__' from './syscall.py'>
  File "/usr/lib/python3.5/multiprocessing/process.py", line 249, in _bootstrap
    self.run()
  File "/usr/lib/python3.5/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/lib/python3.5/multiprocessing/pool.py", line 108, in worker
    task = get()
  File "/usr/lib/python3.5/multiprocessing/queues.py", line 345, in get
    return ForkingPickler.loads(res)
AttributeError: Can't get attribute 'runit' on <module '__main__' from './syscall.py'>

1 个答案:

答案 0 :(得分:3)

我不确定,因为我所知道的问题与Windows相关(而且我无法访问Linux机箱进行重新呈现),但为了便于携带,您必须包装多处理器 - if __name__=="__main__"中的依赖命令或它与python生成进程的方式冲突:固定示例在Windows上运行正常(并且在其他平台上也可以正常工作):

from multiprocessing import Pool
import os

def runit(cmd):
    proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
    return proc.stdout.read()

#print(runit('ls -l'))

it = []
for i in range(1,3):
    it.append('ls -l')

if __name__=="__main__":
    # all calls to multiprocessing module are "protected" by this directive
    pool = Pool()

(更仔细地研究错误消息,现在我非常确定在声明pool = Pool()后移动runit 也会在Linux上解决它,但包装在__main__修复+使其可移植)

那就是说,请注意您的多处理只是创建一个新进程,因此您最好使用线程池(Threading pool similar to the multiprocessing Pool?):创建进程的线程,如下所示:

from multiprocessing.pool import ThreadPool  # uses threads, not processes
import os

def runit(cmd):
    proc = Popen(cmd, shell=True,stdout=PIPE, stderr=PIPE, universal_newlines=True)
    return proc.stdout.read()

it = []
for i in range(1,3):
    it.append('ls -l')

if __name__=="__main__":
    pool = ThreadPool()   # ThreadPool instead of Pool
    results = pool.map(runit, it)
    print(results)
        results = pool.map(runit, it)
        print(results)

后一种解决方案更轻巧,并且不易出错(多处理是一个难以处理的模块)。您将能够使用对象,共享数据等...而不需要Manager对象,以及其他优点