Python多处理:如何安全地更改其中一个进程的工作目录



我需要运行几个并行进程,每个进程执行一组函数。喜欢这个:

import multiprocessing as mp  
data = [set1, set2, set3]  
functions = [func1, func2, func3, func4]  
# each func is run in its own separate directory
def myProcess(dataset, functions_list):  
for func in functions_list:  
func(dataset)  
for set_i in data:  
p = mp.Process(target = myProcess, args = (set_i, functions))  
p.start()  

问题是functions列表中的每个函数都需要在其单独的目录中运行。据我所知,os.chdir切换所有正在运行的进程的目录。如何确保每个进程在适当的目录中安全地运行,而不会突然被另一个进程踢出目录?

你从一个错误的前提开始:

据我所知,os.chdir为所有正在运行的进程切换目录。

不。它切换当前进程的目录,而不是系统上的每个进程(甚至组中的每个进程,或类似的东西(。

当然,如果您在启动子目录之前chdir父目录,则子目录将从该新目录中启动。但是,如果您chdir任何孩子,则不会影响其他任何人。而且如果你在开始孩子后chdir父母,它也不会影响其他人。


如何确保每个进程在适当的目录中安全地运行,而不会突然被另一个进程踢出目录?

你不需要做任何事情;这就是每个操作系统已经工作的方式。


如果要自己验证这一点,请尝试运行此程序。在您想要的任何平台上,使用该平台支持的每个startmethod,您都会看到子级可以独立更改目录,而不会影响彼此或父级。

import multiprocessing
import os
def func():
pid = str(os.getpid())
print(f'{pid}: {os.getcwd()}')
try:
os.mkdir(pid)
except FileExistsError:
pass
os.chdir(pid)
print(f'{pid}: {os.getcwd()}')
if __name__ == '__main__':
import sys
startmethod = sys.argv[1] if len(sys.argv)>1 else 'fork'
multiprocessing.set_start_method(startmethod)
print(f'{os.getpid()}: {os.getcwd()}')
children = [multiprocessing.Process(target=func) for _ in range(2)]
for child in children:
child.start()
for child in children:
child.join()
print(f'{os.getpid()}: {os.getcwd()}')
事实上,

每个进程都将彼此独立并运行 os.chdir 中的每一个将只为运行它的进程完成。

如果您采用具有三个文件夹 a、b、c 的结构。

此代码将为每个文件夹创建一个进程,该进程将在其中创建一个文件。

每个进程在创建文件之前等待 5 秒。因此,如果 os.chdir 正在更改所有进程的目录,它们都将在同一目录中创建文件。您将看到情况并非如此,并且为每个目录创建一个文件。

因此,os.chdir 不会更改所有进程的目录 如果它在进程运行的函数中执行。

from multiprocessing import Process
import time
import os

def write_hello_world(directory):
"""Open a file with the same name as the directory in the directory
In folder a we will create a file named a.
:param str directory: directory where the file will be created.
"""
os.chdir(directory)
# We wait 5 seconds, all processes should have been started and changed directory.
time.sleep(5)
with open(directory, "w+") as f:
# We write in the file the value of the directory
f.write(directory)

# List of the process to join them in the end.
list_processes = []
# for each folder we create a process and we start it.
for directory in ["a", "b", "c"]:
p = Process(target=write_hello_world, args=(directory,))
p.start()
# Join the processes.
for process in list_processes:
process.join()

祝你有美好的一天。

相关内容

  • 没有找到相关文章

最新更新