如何将未腌制的对象作为参数传递给multiprocessing.Process?

时间:2019-08-04 15:21:33

标签: python multiprocessing queue pickle python-multiprocessing

我正在解开一个对象并作为用于过程的args之一传递。无输出。

我想知道这种取消选择和传递对象作为参数的方法是否会引起多处理错误。为此将有什么解决方法?

from multiprocessing import Process, Queue
def func(arg1, arg2,q):
    df_temp = arg1[arg1['col'].isin(arg2)]
    q.put(df_temp)

if __name__ == '__main__':
    import pickle
    import pandas as pd
    arg1= pickle.load(open('paths.p','rb'))
    arg2= pd.Series(pd.date_range(end = 'some_Date', periods=12,freq = 'MS')).dt.to_pydatetime()
    arg2=[i.date() for i in arg2]
    q = Queue()
    p =Process(target=func, args=(arg1,arg2,q))
    p.start()
    p.join()    
    while not q.empty():
        w=q.get() 

1 个答案:

答案 0 :(得分:2)

您由于其他原因陷入僵局。

  

默认情况下,如果进程不是队列的创建者,则在退出时   它将尝试加入队列的后台线程。该过程可以   调用cancel_join_thread()使join_thread()什么都不做。 docs

您的Process不会退出,因为它正在从multiprocessing.Queue加入馈线线程,该线程将在您第一次queue.put()时启动。您需要queue.get()在您父母的之前加入该过程。

  

警告::如上所述,如果子进程将项目放置在   队列(它尚未使用JoinableQueue.cancel_join_thread),然后   直到所有缓冲的项目都已完成,该过程才会终止   冲洗到管道。这意味着如果您尝试加入该过程   您可能会陷入僵局,除非您确定所有具有   被放在队列中已被消耗掉。同样,如果孩子   进程是非守护进程,则父进程可能在以下情况退出时挂起   它尝试加入其所有非守护进程的子级。 docs

也不要使用while not q.empty(),它是一种反模式,一旦有多个使用者,就会导致死锁。 请使用哨兵值来通知消费者不再有其他物品。有关更多信息,here