很抱歉......似乎我问了一个热门问题,但我找不到任何有用的问题来自stackflow:P
所以我的代码执行以下操作:
步骤1.父进程将任务对象写入multiprocessing.JoinableQueue
步骤2.子进程(超过1)从JoinableQueue读取(获取)任务对象并执行任务
我的模块结构是:
A.py
课程任务(对象)
类WorkerPool(对象)
Class Worker(multiprocessing.Process)
Class TestGroup()
我所理解的是当使用mp.JoinableQueue时,附加的对象应该是可选择的,我得到了"可选择的"来自https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled
我的问题是: 1.在我的情况下,Task的对象是否可以选择?
当代码将任务对象附加到JoinableQueue中时,我收到了以下错误:
文件" /usr/lib/python2.6/multiprocessing/queues.py" ;,第242行,在_feed
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失败
mp.JoinableQueue的一般用法是什么?在我的情况下,我需要使用join()和task_done()
当我选择使用Queue.Queue而不是mp.JoinableQueue时,pickerror就不见了。但是,从日志中检查,我发现所有子进程都在继续处理Queue的第一个对象,这种情况的可能原因是什么?
答案 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用于线程化。它使用共享内存和同步机制来提供原子操作。但是,当您使用多处理启动新进程时,它会复制初始进程,因此每个子进程都将处理相同的队列对象,因为已为每个进程复制了内存中的队列。