我需要运行几个并行进程,每个进程执行一组函数。喜欢这个:
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()
祝你有美好的一天。