在Windows上调用Python 3.11中的多处理

时间:2018-04-24 06:11:11

标签: python windows multiprocessing

我在Windows上的Python 3.11中遇到了多处理问题。

这是脚本:

from multiprocessing import Process
import os
import time

def info(title):
        print(title)
        print('module name:', __name__)
        if hasattr(os, 'getppid'):  # only available on Unix
               print('parent process:', os.getppid())
        print('process id:', os.getpid())

def f(name):
        info('function f')
        print('--- hello', name)
        time.sleep(5)
        print('--- bye', name)

def some_func():
        print('Running some_func function')

def another_func():
        print('Running another_func function')


def main():
        print('Running main function of try_multi.py')
        print('-------------------------------------')
        some_func()
        if __name__ == '__main__':
               info('main line')
               p1 = Process(target=f, args=('bob',))
               p2 = Process(target=f, args=('larry',))
               p1.start()
               p2.start()
               p1.join()
               p2.join()
        another_func()

main()

这是输出:

C:\Scripts> c:\Python31\python.exe try_multi.py
Running main function of try_multi.py
-------------------------------------
Running some_func function
main line
module name: __main__
process id: 12696
Running main function of try_multi.py
-------------------------------------
Running some_func function
Running another_func function
function f
module name: __main__
process id: 14568
--- hello bob
Running main function of try_multi.py
-------------------------------------
Running some_func function
Running another_func function
function f
module name: __main__
process id: 9336
--- hello larry
--- bye bob
--- bye larry
Running another_func function

问题是我希望只有函数“f”在新进程中运行,但看起来父脚本的全新实例都已启动 - “some_fun”和“another_func”都会运行。

在使用Python 2.7.5的Linux上,它按预期工作:

$ python try_multi.py
Running main function of try_multi.py
-------------------------------------
Running some_func function
main line
('module name:', '__main__')
('parent process:', 1137)
('process id:', 1167)
function f
('module name:', '__main__')
('parent process:', 1167)
('process id:', 1168)
('--- hello', 'bob')
function f
('module name:', '__main__')
('parent process:', 1167)
('process id:', 1169)
('--- hello', 'larry')
('--- bye', 'bob')
('--- bye', 'larry')
Running another_func function

我能否在平台上正常工作(Windows上的Python 3.11)? 谢谢

1 个答案:

答案 0 :(得分:3)

在文档中的Programming Guidelines中解释了这一点:

  

确保新的Python解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)。

一般来说,这意味着您想要更改脚本的最后一行:

main()

......对此:

if __name__ == '__main__':
    main()

否则,每个新的子进程都会启动并立即尝试调用main并生成两个新进程。无论这种情况是深入的,还是无限深入的,并且对您的系统进行forkbombs,或者引发异常取决于各种不值得进入的细节,但它永远不会在Windows上做正确的事情。

如果你想知道为什么它可以在Linux上运行:在Windows上,multiprocessing通过启动一个全新的Python解释器并使其导入并运行你的模块来工作,因此模块中的所有顶级代码都可以获得跑;在Linux上,它通过分支当前解释器进程的副本然后从那里启动任务来工作,因此它实际上不需要重新运行脚本,因此顶级代码通常不会被重新执行。 / p>

在Python的后续版本(3.1非常古老......)中,他们已经清理了一些东西,并使它们更加灵活,因此您可以通过指定{在两个平台上获得相同的行为来做好事。 {1}}。但基本的默认结果将是相同的。