在main和worker进程中导入不同的模块集

时间:2018-04-09 20:56:51

标签: python python-import python-multiprocessing

使用多进程模块时,是否有可能让Process导入另一个库?例如:

import multiprocessing as mp
import pprint
import sys
import threading

from Foo import Moo

class Worker(mp.Process):
    def __init__(self):
        print "Worker Init"
        mp.Process.__init__(self)

    def run(self):
        print "Worker Running"
        self._static_method()

    @staticmethod
    def _static_method():
        print "I'm a-static, get it?"

class TouchWorker(threading.Thread):
    def __init__(self):
        super(TouchWorker, self).__init__(name="Touchoo" + " TouchWorker")

    def run(self):
        print "Touchoo Running"

class Parasite(mp.Process):
    def __init__(self):
        print "Parasite Init"
        mp.Process.__init__(self)

    def run(self):
        print "Parasite Running"

class Encapsulator(object):
    def __init__(self):
        workers = []

        for _ in range(4):
            wrk = Worker()
            workers.append(wrk)

        for someWorker in workers:
            someWorker.start()

        par = Parasite()
        par.start()

if __name__ == '__main__':
    enc = Encapsulator()

我只需要'工人'和'寄生虫'流程中的'Foo'模块。是否有可能让他们在运行时导入该模块?

2 个答案:

答案 0 :(得分:1)

简单地颠倒防止无限循环创建过程所需的习惯用法。

# this should look familiar
if not __name__ == "__main__":
     from Foo import Moo

您可能会发现,让您的库加载更快更容易,只需在主文件中执行它,以避免各种荒谬的范围问题。这可以通过在子进程启动时要求单独的Moo.initialize()调用来实现,但是它需要由每个子进程执行,因为内存不是共享的。

一个好的一般经验法则是库在导入时不应该执行任何实际操作,以便快速加载它们。一旦从所述库调用函数或类,就会执行必要的工作。

答案 1 :(得分:0)

为了生成子进程,multiprocessing在UNIX中使用fork()并在Windows中运行带有特殊参数的程序,该程序调用试图模拟相同行为的特殊代码。

因此,当您的子进程被创建时,它们实际上并未再次初始化,所有已加载父模块的模块也已为它们加载。

所以,如果你想导入一个模块:

  • 在主人但不在工人中:
    • 不可能,而且完全没有必要。您所能做的就是使引用模块的变量以某种方式对工人不可见
  • 在工人中但不在工作人员中:
    • import里面的工作者功能
      • 导入将在每个工作人员中完成,或
    • import它在主人
      • 导入将在master中完成一次,子项将自动继承,或
    • import在master中,然后del生成的变量(这样它不会污染主服务器的名称空间),然后再次在工作程序中import(将重用现有模块)对象来自sys.modules