我将多处理库与python 3.7一起使用,其父进程通过队列与子进程进行对话。我可以使用multiprocessing.queue.Queue很好,但是当我通过子类向队列添加一些额外的功能时,它们在父级中的设置就很好了,但是在子级访问时似乎丢失了。知道如何让属性保留在孩子中吗?
import sys
import time
import multiprocessing
import multiprocessing.queues
# Subclass multiprocessing.queue.Queue to add some useful features
class q_class(multiprocessing.queues.Queue):
def __init__(self):
self.report_bottlenecks = False
self.bottleneck_time = 1.0 #in seconds
super(q_class, self).__init__(ctx=multiprocessing.get_context())
def put(self,header,payload=None):
message = {}
message['header'] = header
message['payload'] = payload
message['put_time'] = time.time()
super(q_class, self).put(message)
def get(self):
message = super(q_class, self).get()
message['get_time'] = time.time()
message['queue_time'] = message['get_time'] - message['put_time']
if self.report_bottlenecks:
if message['queue_time']>self.bottleneck_time:
self.debug.print('Queue bottleneck: '+str(int(message['queue_time']))+' seconds.')
return(message)
def function_for_child_to_run(the_q):
print('Child process started')
print(the_q.report_bottlenecks) #currently causes an AttributeError: 'q_class' object has no attribute 'report_bottlenecks'
if __name__ == '__main__':
multiprocessing.set_start_method('forkserver')
my_q = q_class()
print(my_q.report_bottlenecks) #should print "False"
process = multiprocessing.Process( target=function_for_child_to_run , args=(my_q,) )
process.start()
time.sleep(2) #give the child time to start & print
process.join()
sys.exit()
答案 0 :(得分:0)
要与forkserver一起使用,必须对队列进行腌制。 multiprocessing.queues.Queue
定义了__getstate__
和__setstate__
方法来酸洗和取消酸洗实例属性。将属性添加到子类Queue时,必须使用自定义属性扩展这两种方法,否则它们会丢失。
将此添加到您的代码中:
from multiprocessing import context
...
class QClass(multiprocessing.queues.Queue):
...
def __getstate__(self):
context.assert_spawning(self)
return (self._ignore_epipe, self._maxsize, self._reader, self._writer,
self._rlock, self._wlock, self._sem, self._opid,
self.report_bottlenecks, self.bottleneck_time) # <---
def __setstate__(self, state):
(self._ignore_epipe, self._maxsize, self._reader, self._writer,
self._rlock, self._wlock, self._sem, self._opid,
self.report_bottlenecks, self.bottleneck_time) = state # <---
self._after_fork()