多进程似乎使用单个逻辑核心

时间:2016-11-15 20:27:14

标签: python python-multiprocessing

我正在尝试执行不同进程可以调用的共享函数。找到的唯一方法是创建一个包含此函数的类(请参阅this previous question)。但是现在我遇到的问题是进程似乎在等待某些东西,因此只使用单个逻辑核心的功能(参见图像)。

我已成功使用以下代码重现相同的问题(已简化):

#!/usr/bin/python

from multiprocessing import Pool
from multiprocessing.managers import BaseManager
from itertools import repeat

class FunctionManager(BaseManager):
    pass

class MaClass:
    def maFunction(self, val):
        print(str(val))
        for i in range(0, 10000):
            for j in range(0, 10000):
                for k in range(0, 10000):
                    pass

FunctionManager.register('MaClass', MaClass)

myManager = FunctionManager()
myManager.start()
monObjet = myManager.MaClass()

p = Pool()
p.imap_unordered(monObjet.maFunction, range(10))
p.close()
p.join()

myManager.shutdown()

HTOP CPU USAGE

有什么想法吗?

1 个答案:

答案 0 :(得分:2)

monObject不是常规类实例,它是实例的代理<class 'multiprocessing.managers.AutoProxy[MaClass]'>。当子进程调用该代理时,该请求将返回到处理它的父进程。执行代理的后台线程仍然受GIL的约束,因此,无论有多少子进程调用它,它一次只能执行其中一个线程。

在池中运行代理方法并不常见。我很欣赏你刚刚编写了一个例子,可能真的需要在父级中运行该方法,但这里有一个简单的例子,可以让孩子保持工作

#!/usr/bin/python

from multiprocessing import Pool

def worker(val):
    c = MaClass()
    return c.maFunction(val)

class MaClass:
    def maFunction(self, val):
        print(str(val))
        for i in range(0, 10000):
            for j in range(0, 10000):
                for k in range(0, 10000):
                    pass

p = Pool()
p.imap_unordered(worker, range(10))
p.close()
p.join()