是否可以在带有Windows的模块中使用多处理?

时间:2016-06-09 22:16:40

标签: python windows multiprocessing

我目前正在浏览一些预先存在的代码,目的是加快速度。有几个地方非常适合并行化。由于Python有GIL,我以为我会使用多进程模块。

但是根据我的理解,这种方法在Windows上运行的唯一方法是,如果我使用if __name__=='__main__'安全措施从最高级别的脚本调用需要多个进程的函数。但是,这个特定的程序是作为一个模块进行分发和导入的,所以让用户复制并粘贴该安全措施是一种笨重的东西,这是我真的想避免做的事情。

就多处理而言,我是否运气不好或误解了什么?或者还有其他方法可以用Windows吗?

3 个答案:

答案 0 :(得分:1)

对于仍在搜索的所有人:

内部模块

from multiprocessing import Process
    
def printing(a):
    print(a)

def foo(name):
    var={"process":{}}
    if name == "__main__":
        for i in range(10):
            var["process"][i] = Process(target=printing , args=(str(i)))
            var["process"][i].start()

        for i in range(10):
            var["process"][i].join

在main.py内部

import data

name = __name__

data.foo(name)

输出:

>>2
>>6
>>0
>>4
>>8
>>3
>>1
>>9
>>5
>>7

我是一个完全菜鸟,所以请不要判断编码或显示方式,但至少可以使用。

答案 1 :(得分:0)

在ms-windows上,您应该能够导入程序的主模块而不会产生副作用,例如启动进程。

当Python导入模块时,它实际上运行它。

所以这样做的一种方法是if __name__ is '__main__'块。

另一种方法是在函数中执行此操作。

以下内容不适用于ms-windows:

from multiprocessing import Process

def foo():
    print('hello')

p = Process(target=foo)
p.start()

这是因为它在导入模块时尝试启动进程。

编程指南中的以下示例是正确的:

from multiprocessing import Process, freeze_support, set_start_method

def foo():
    print('hello')

if __name__ == '__main__':
    freeze_support()
    set_start_method('spawn')
    p = Process(target=foo)
    p.start()

因为导入模块时if块中的代码不会运行。

但是把它放在一个函数中也应该有效:

from multiprocessing import Process

def foo():
    print('hello')

def bar()
    p = Process(target=foo)
    p.start()

运行此模块时,它将定义两个新功能,而不是运行。

答案 2 :(得分:0)

正如评论中所解释的,也许你可以做类似

的事情
#client_main.py
from mylib.mpSentinel import MPSentinel

#client logic

if __name__ == "__main__":
    MPSentinel.As_master()

#mpsentinel.py

class MPSentinel(object):

    _is_master = False

@classmethod
def As_master(cls):
    cls._is_master = True

@classmethod
def Is_master(cls):
    return cls._is_master

它不是理想的,因为它实际上是单身/全局,但它可以解决窗口缺乏分叉的问题。你仍然可以使用MPSentinel.Is_master()来选择使用多处理,它应该阻止Windows进行进程轰炸。