如何防止多处理继承导入和全局变量?

问题描述 投票:0回答:3

我在更大的代码库中使用多重处理,其中一些导入语句具有副作用。如何在后台进程中运行函数而不让它继承全局导入?

# helper.py:

print('This message should only print once!')
# main.py:

import multiprocessing as mp
import helper  # This prints the message.

def worker():
  pass  # Unfortunately this also prints the message again.

if __name__ == '__main__':
  mp.set_start_method('spawn')
  process = mp.Process(target=worker)
  process.start()
  process.join()

背景:导入TensorFlow会初始化CUDA,CUDA会保留一定量的GPU内存。因此,生成太多进程会导致 CUDA OOM 错误,即使这些进程不使用 TensorFlow。

类似问题没有答案:

python tensorflow multiprocessing
3个回答
2
投票

是否有资源可以准确解释多处理 启动

mp.Process
时模块会做什么?

超级快速版本(使用spawn context而不是fork)

准备一些东西(一对用于通信的管道,清理回调等),然后使用

fork()
exec()
创建一个新进程。在 Windows 上,它是
Create
ProcessW()
。新的 python 解释器通过启动脚本
spawn_main()
进行调用,并通过 精心设计的命令字符串
-c
开关传递通信管道文件描述符。启动脚本稍微清理环境,然后从其通信管道中unpickles
Process
对象
。最后它调用流程对象的
run
方法。

那么导入模块怎么样?

Pickle 语义处理其中的一些,但是

__main__
sys.modules
需要一些 tlc,这是在 here 处理的(在“清理环境”期间)。


0
投票
# helper.py:

print('This message should only print once!')
# main.py:

import multiprocessing as mp

def worker():
  pass

def main():

  # Importing the module only locally so that the background
  # worker won't import it again.
  import helper

  mp.set_start_method('spawn')
  process = mp.Process(target=worker)
  process.start()
  process.join()

if __name__ == '__main__':
  main()

0
投票

使用flask和gunicorn运行服务器,

__name__
multiprocessing.parent_process()
都无法区分父进程和子进程,所以我必须在为子进程明确设置它后使用
multiprocessing.current_process().name

import multiprocessing as mp

def child_process():
    pass

if mp.current_process().name != "the_child":
    import numpy # Or other expensive/side-effect imports

    process = mp.Process(target=child_process, name="the_child")
    process.start()
    process.join()
© www.soinside.com 2019 - 2024. All rights reserved.