Python 如何使用joblib并行写入文件?可连接队列问题

Python 如何使用joblib并行写入文件?可连接队列问题,python,python-3.x,multiprocessing,joblib,Python,Python 3.x,Multiprocessing,Joblib,我试图将运行超过100k+个文件的计算结果写入单个文件。处理一个文件需要~1秒,并将一行写入输出文件。问题本身是“令人尴尬的平行”,我只是在努力正确地写入文件(比如CSV)。下面是很久以前对我有用的东西(Python 3.4?): 今天(在Python 3.6+上),它产生以下异常: joblib.externals.loky.process_executor._RemoteTraceback: """ (...) RuntimeError: JoinableQueue objects sho

我试图将运行超过100k+个文件的计算结果写入单个文件。处理一个文件需要~1秒,并将一行写入输出文件。问题本身是“令人尴尬的平行”,我只是在努力正确地写入文件(比如CSV)。下面是很久以前对我有用的东西(Python 3.4?):

今天(在Python 3.6+上),它产生以下异常:

joblib.externals.loky.process_executor._RemoteTraceback: 
"""
(...)
RuntimeError: JoinableQueue objects should only be shared between processes through inheritance
"""

如何使用joblib正确写入单个文件?

事实证明,实现该任务的一种方法是通过
多处理.Manager
,如下所示:

import os
from multiprocessing import Process, Manager
from joblib import Parallel, delayed

def save_to_file(q):
    with open('test.csv', 'w') as out:
        while True:
            val = q.get()
            if val is None: break
            out.write(val + '\n')

def process(x):
    q.put(str(os.getpid()) + '-' + str(x**2))

if __name__ == '__main__':
    m = Manager()
    q = m.Queue()
    p = Process(target=save_to_file, args=(q,))
    p.start()
    Parallel(n_jobs=-1)(delayed(process)(i) for i in range(100))
    q.put(None)
    p.join()
我们让
管理器
管理上下文,其余部分保持不变(除了使用正常的
队列
代替
可连接队列


如果有人知道更好/更干净的方法,我会很乐意接受它作为答案。

对于
q.put(str(os.getpid())+'-'+str(x**2))
q
在范围上从何而来?joblib是否处理将整个外部作用域传递给
进程
,从而访问
q
对象?后续:我尝试传递一个file对象,而不是每次需要写入
文件时都打开
文件,但似乎没有得到任何输出。知道为什么会这样吗?
import os
from multiprocessing import Process, Manager
from joblib import Parallel, delayed

def save_to_file(q):
    with open('test.csv', 'w') as out:
        while True:
            val = q.get()
            if val is None: break
            out.write(val + '\n')

def process(x):
    q.put(str(os.getpid()) + '-' + str(x**2))

if __name__ == '__main__':
    m = Manager()
    q = m.Queue()
    p = Process(target=save_to_file, args=(q,))
    p.start()
    Parallel(n_jobs=-1)(delayed(process)(i) for i in range(100))
    q.put(None)
    p.join()