[英]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 上, 生成上下文是创建工作进程的唯一方法。
sys.argv
被复制到工作进程一次。
并非所有文件都重新导入。 只需要模块来解开任务function和 arguments 被导入。
在worker中,原来的__main__
实际上叫做__mp_main__
。 复制sys.argv
后,worker 导入__mp_main__
,其中导入test
,因此env
设置正确。
尽管multiprocessing
试图保持环境相似,但工作进程入口点位于multiprocessing.spawn
中的某个位置。 那里提到了几个项目: sys.argv
, sys.path
, os.getcwd()
。 有关详细信息,请参阅get_preparation_data()
和prepare()
。
可以通过任务管理器或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.