繁体   English   中英

Python 多处理和 sys.argv

[英]Python multiprocessing and sys.argv

sys.argv值是否传递到多处理的分支? 将 argv 传递给多进程的所有分支的正确方法是什么?

假设我有两个文件:test1.py:

import sys
if len(sys.argv) > 1:
    env = sys.argv[1]
else:
    env = 'test'

和 main_code.py:

from test1 import *
import concurrent.futures


def f():
    if env == 'test':
        print('bu')
    else:
        print('not bu')

if __name__ == '__main__':
    with concurrent.futures.ProcessPoolExecutor(max_workers=2) as executor:
        for i in range(2):
            executor.submit(f)

我从 cmd main.code.py: python main_code.py zzz调用。 sys.argv[1] 变量(即“zzz”)是否在每次调用executor.submit(f)时传递,因为它是从 text1.py 的导入中首次获得的? 我的困惑来自这样一个事实,即 concurrent.futures 基本上通过重新导入所有文件来创建单独的代码线程实例。

在 Windows 上, 生成上下文是创建工作进程的唯一方法。

  1. sys.argv被复制到工作进程一次。

  2. 并非所有文件都重新导入。 只需要模块来解开任务function和 arguments 被导入。

  3. 在worker中,原来的__main__实际上叫做__mp_main__ 复制sys.argv后,worker 导入__mp_main__ ,其中导入test ,因此env设置正确。

  4. 尽管multiprocessing试图保持环境相似,但工作进程入口点位于multiprocessing.spawn中的某个位置。 那里提到了几个项目: sys.argvsys.pathos.getcwd() 有关详细信息,请参阅get_preparation_data()prepare()

  5. 可以通过任务管理器或ps命令验证worker进程是以不同的arguments启动的。

我编写了一个名为mp.py的简单脚本,通过运行python3 mp.py hello world来打印 arguments。

Output:

29836 process ['C:/xxxx/stackoverflow/mp.py'] <module '__main__' from 'C:/xxxx/stackoverflow/mp.py'>
29836 my name is main
29836 true main <module '__main__' from 'C:/xxxx/stackoverflow/mp.py'>
18464 process ['C:\\xxxx\\stackoverflow\\mp.py'] <module '__main__' (built-in)>
18464 worker <module '__mp_main__' from 'C:\\xxxx\\stackoverflow\\mp.py'>

mp.py:

from __future__ import annotations

import multiprocessing
import os
import sys
import time
from concurrent.futures import ProcessPoolExecutor


def list_modules(who_am_i):
    the_main = sys.modules.get('__main__')
    print(os.getpid(), who_am_i, the_main)


def main():
    list_modules('true main')
    mp_context = multiprocessing.get_context('spawn')
    # mp_context = multiprocessing.get_context('fork')
    # mp_context = multiprocessing.get_context('forkserver')
    with ProcessPoolExecutor(1, mp_context=mp_context) as executor:
        executor.submit(list_modules, 'worker').result()

        time.sleep(100)


# This message is print when this module is loaded. (none in fork, once in forkserver, multiple times in spawn)
print(os.getpid(), "process", sys.argv, sys.modules.get('__main__'))

if __name__ == '__main__':
    # Print once in the main process
    print(os.getpid(), "my name is main")
    main()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM