Python multiprocessing.Queue修改对象
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Python multiprocessing.Queue修改对象,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3464字,纯文字阅读大概需要5分钟。
内容图文
![Python multiprocessing.Queue修改对象](/upload/InfoBanner/zyjiaocheng/815/ab352f6d37f54d57932b95e77263204a.jpg)
我有一个应用程序,它实现了像Python中的责任链.有一个进程通过multiprocessing.Queue()将对象传递给其他进程,然后其他进程对对象执行操作.对于被跟踪的对象的最后修改时间也很重要,因此只有在修改对象时才能执行操作.
我遇到的问题是,从队列中提取后,对象中的_modified属性似乎会随机变化.但是,_mtime属性始终是正确的.下面的示例将运行并(有意)随机修改DummyObject,然后将其放在每个处理程序进程的Queue上.然后,每个处理程序将打印它们在对象中收到的_modified和_mtime值.我希望_modified值在command_func和handler函数中都是相同的,但通常情况并非如此.如果我从DummyObject中删除Object_w_mtime继承,那么我看不到发送和接收对象的任何差异.
我对python比较陌生.据我所知,应该发生的事情是每次将一个对象放在一个队列上,它被腌制,然后通过一个管道发送到接收进程,该进程将对象取消.那是对的吗?当对象被pickle / unpickled时,有没有任何方法可以搞砸对象继承?
我在Ubuntu 11.10上用Python 2.7.2和2.6.7以及Ubuntu 11.04上的python 2.7.1测试了这个.有时你必须让它运行一分钟左右才能看到行为,因为它似乎是随机的.
在这里抓住稻草,提前谢谢.
import multiprocessing
import time
import traceback
import os
import random
class Object_w_mtime(object):
'''
Parent object that tracks the last time an attribute was modified
'''
def __setattr__(self,a_name,a_value):
if ((a_name not in ('_mtime','_modified')) and
(a_value != getattr(self,a_name,None))
):
object.__setattr__(self, '_modified', True)
object.__setattr__(self, '_mtime', time.time())
object.__setattr__(self, a_name, a_value)
return True
#END def
def reset(self):
self._modified = False
#END class
class DummyObject(Object_w_mtime):
def __init__(self):
self.value = 10
def handler(in_queue = None, handler_id = None):
print 'PID:' + str(os.getpid()) + ':handler{0}:<RUN>'.format(handler_id)
while True:
try:
obj = in_queue.get(True,61)
print 'handler{} - _modified'.format(handler_id), obj._modified, ' \t_mtime', obj._mtime
except multiprocessing.queues.Empty:
break
except KeyboardInterrupt:
break
except Exception as e:
print traceback.format_exc()
break
return True
#END def
def command_func(next_links = None):
print 'PID:' + str(os.getpid()) + ':command_func:<RUN>'
obj = DummyObject()
while True:
try:
# randomly assign a different value to test with a modified and unmodified object
obj.value = random.randint(0,1)
print '**************** obj.value = {0} ***************'.format(obj.value)
print 'command_ - _modified', obj._modified, ' \t_mtime', obj._mtime
for each in next_links:
each.put(obj,False)
except multiprocessing.queues.Empty:
break
except KeyboardInterrupt:
break
except Exception as e:
print e
print traceback.format_exc()
break
obj.reset()
time.sleep(3)
return True
#END def
if __name__ == '__main__':
handler_queues = list()
handler_processes = list()
# Create a queue and process object for each command handler
for handler_id in range(1,4):
queue = multiprocessing.Queue()
process = multiprocessing.Process(target=handler, args=(queue, handler_id))
handler_queues.append(queue)
handler_processes.append(process)
try:
# spawn handler processes
for process in handler_processes:
process.start()
# Start sending commands to handlers
command_func(handler_queues)
# exit on keyboard interrupt
except KeyboardInterrupt:
for process in handler_processes:
process.join()
except Exception:
traceback.print_exc()
解决方法:
简而言之,您将obj放入队列后进行修改.
查看http://svn.python.org/view/python/trunk/Lib/multiprocessing/queues.py?revision=76434&view=markup第285行,put()仅将对象放在内部队列中,如果尚未运行,则启动后台线程以处理该队列中的对象.因此,代码中的each.put(obj,False)和obj.reset()之间存在争用.
您应该只使用具有不可变(副本)对象的队列.
内容总结
以上是互联网集市为您收集整理的Python multiprocessing.Queue修改对象全部内容,希望文章能够帮你解决Python multiprocessing.Queue修改对象所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。