Python 多进程更改每个进程的当前文件夹

Python 多进程更改每个进程的当前文件夹,python,multithreading,multiprocessing,Python,Multithreading,Multiprocessing,我正在尝试使用多处理模块来并行一些计算 如何确保由multiprocessing.Pool.map\u async生成的每个进程都在不同的(以前创建的)文件夹上运行 问题是,每个进程都会调用一些将临时文件写入磁盘的第三方库,如果在同一个文件夹中运行许多临时文件,就会把一个文件和另一个文件弄乱 此外,我不能为map_async进行的每个函数调用创建一个新文件夹,而是希望创建尽可能少的文件夹(即,每个进程一个) 代码与此类似: import multiprocessing,os,shutil pro

我正在尝试使用
多处理
模块来并行一些计算

如何确保由
multiprocessing.Pool.map\u async
生成的每个进程都在不同的(以前创建的)文件夹上运行

问题是,每个进程都会调用一些将临时文件写入磁盘的第三方库,如果在同一个文件夹中运行许多临时文件,就会把一个文件和另一个文件弄乱

此外,我不能为map_async进行的每个函数调用创建一个新文件夹,而是希望创建尽可能少的文件夹(即,每个进程一个)

代码与此类似:

import multiprocessing,os,shutil
processes=16

#starting pool
pool=multiprocessing.Pool(processes)

#The asked dark-magic here?

devshm='/dev/shm/'
#Creating as many folders as necessary
for p in range(16):
    os.mkdir(devshm+str(p)+'/')
    shutil.copy(some_files,p)

def example_function(i):
    print os.getcwd()
    return i*i
result=pool.map_async(example_function,range(1000))
因此,在任何时候,示例_函数的每次调用都会在不同的文件夹上执行

我知道一个解决方案可能是使用子进程生成不同的进程,但我希望坚持多进程(我需要为每个生成的子进程pickle一些对象、写入磁盘、读取、取消pickle,而不是通过函数调用传递对象本身(使用functools.partial)

附言

在某种程度上是相似的,但该解决方案不能保证每个函数调用都发生在不同的文件夹中,这确实是我的目标。

由于您在问题中没有指定,我假设您在函数完成执行后不需要目录的内容

最简单的方法是在使用临时目录的函数中创建和销毁临时目录。这样,代码的其余部分就不关心工作进程的环境/目录,而且
非常适合。我还将使用python的内置功能创建临时目录:

import multiprocessing, os, shutil, tempfile
processes=16

def example_function(i):
    with tempfile.TemporaryDirectory() as path:
        os.chdir(path)
        print(os.getcwd())
        return i*i

if __name__ == '__main__':
    #starting pool
    pool=multiprocessing.Pool(processes)

    result=pool.map(example_function,range(1000))
注意:是在python 3.2中引入的。如果您使用的是较旧版本的python,则可以

如果您确实需要预先设置目录

尝试使用
进行此操作有点麻烦。您可以传递要与数据一起使用的目录名,但只能传递与目录数相等的初始数量。然后,您需要使用类似
imap\u unordered
的方法来查看何时完成结果(其目录可供重用)

在我看来,更好的方法不是使用
,而是创建单独的
进程
对象,并将每个对象分配到一个目录。如果需要控制
进程
环境的某个部分,这通常会更好,如果问题是由数据驱动的,则
通常会更好nd不关心进程或它们的环境

向流程对象传递数据和从流程对象传递数据有不同的方法,但最简单的方法是队列:

import multiprocessing,os,shutil
processes=16

in_queue = multiprocessing.Queue()
out_queue = multiprocessing.Queue()

def example_function(path, qin, qout):
    os.chdir(path)

    for i in iter(qin.get, 'stop'):
        print(os.getcwd())
        qout.put(i*i)


devshm='/dev/shm/'
# create processes & folders
procs = []
for i in range(processes):
    path = devshm+str(i)+'/'
    os.mkdir(path)
    #shutil.copy(some_files,path)

    procs.append(multiprocessing.Process(target=example_function, args=(path,in_queue, out_queue)))
    procs[-1].start()


# send input
for i in range(1000):
    in_queue.put(i)
# send stop signals
for i in range(processes):
    in_queue.put('stop')

# collect output    
results = []
for i in range(1000):
    results.append(out_queue.get())