python多处理JoinableQueue PicklingError

时间:2014-06-23 10:57:12

标签: python queue multiprocessing

很抱歉......似乎我问了一个热门问题,但我找不到任何有用的问题来自stackflow:P

所以我的代码执行以下操作:

步骤1.父进程将任务对象写入multiprocessing.JoinableQueue

步骤2.子进程(超过1)从JoinableQueue读取(获取)任务对象并执行任务

我的模块结构是:

A.py

  • 课程任务(对象)

  • 类WorkerPool(对象)

  • Class Worker(multiprocessing.Process)

    • def run()#这里执行第2步
  • Class TestGroup()

    • def loadTest()#这里执行上面的步骤1,即附加Task
    • 的对象

我所理解的是当使用mp.JoinableQueue时,附加的对象应该是可选择的,我得到了"可选择的"来自https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled

我的问题是: 1.在我的情况下,Task的对象是否可以选择?

  1. 当代码将任务对象附加到JoinableQueue中时,我收到了以下错误:

    文件" /usr/lib/python2.6/multiprocessing/queues.py" ;,第242行,在_feed

  2. 2014-06-23 03:18:43 INFO TestGroup:G1结束负载测试:object1

    2014-06-23 03:18:43 INFO TestGroup:G1结束负载测试:object2

    2014-06-23 03:18:43 INFO TestGroup:G1结束负载测试:object3     发送(OBJ)

    PicklingError:无法挑剔:属性查找pysphere.resources.VimService_services_types.DynamicData_Holder失败

    1. mp.JoinableQueue的一般用法是什么?在我的情况下,我需要使用join()和task_done()

    2. 当我选择使用Queue.Queue而不是mp.JoinableQueue时,pickerror就不见了。但是,从日志中检查,我发现所有子进程都在继续处理Queue的第一个对象,这种情况的可能原因是什么?

1 个答案:

答案 0 :(得分:2)

Python中的multiprocessing模块启动多个进程来运行您的任务。由于进程不共享内存,因此它们需要能够使用序列化数据进行通信。多处理使用pickle模块进行序列化,因此要求传递给任务的对象是可选择的。

1)您的任务对象似乎包含来自pysphere.resource.VimService_services_types的实例。这可能是对系统资源的引用,例如打开的文件。这不能序列化或从一个进程传递到另一个进程,因此会导致酸洗错误。

你可以用mp.JoinableQueue做什么,将你需要的参数传递给任务,并让它在任务本身启动服务,使其成为该过程的本地服务。

例如:

queue = mp.JoinableQueue()
# not queue.put(task), since the new process will create the task
queue.put(task_args)

def f(task_args):
    task = Task(task_args)
    ...
    # you can't return the task, unless you've closed all non-serializable parts
    return task.result

process = Process(target=f, args=(queue,))
... 

2)Queue.Queue用于线程化。它使用共享内存和同步机制来提供原子操作。但是,当您使用多处理启动新进程时,它会复制初始进程,因此每个子进程都将处理相同的队列对象,因为已为每个进程复制了内存中的队列。