【python】带有SyncManager类的python中的多进程优先级队列的队列功能

原文来自stackoverflow


问题描述

我本来想实现多处理优先级队列,所以要用到Queue
但当我写完代码以后。我可以为我的优先级队列使用.get()和.put()函数,但是当我使用.queue打印队列中的当前元素时,它给了我一个错误

 class MyManager(SyncManager):   
    pass

def get_manager():
    MyManager.register("PriorityQueue", PriorityQueue)  # Register a shared PriorityQueue
    m = MyManager()
    m.start()
    return m

m = get_manager()
call= m.PriorityQueue()
for i in range(5):
    call.put(i)

print(call.queue)

错误:AttributeError: ‘AutoProxy[PriorityQueue]’ object has no attribute 'queue’

我阅读了SyncManager的python文档并修改了我的代码。
更改后的代码

class MyManager(SyncManager):   
    pass

def get_manager():
    MyManager.register("PriorityQueue", PriorityQueue,exposed=['put','get','queue'])  # Register a shared PriorityQueue
    m = MyManager()
    m.start()
    return m

m = get_manager()
call= m.PriorityQueue()
for i in range(5):
    call.put(i)

print(call.queue)

现在输出是:

<bound method AutoProxy[PriorityQueue].queue of <AutoProxy[PriorityQueue] object, typeid 'PriorityQueue' at 0x7ff3b48f2dd0>>

我仍然没有获得队列中的元素,我了解了寄存器函数的method_to_typeid属性以映射exposed中提到的函数的返回类型,但是我不知道该如何使用。

解决办法

对于Queue来说,只能通过代理使用引用对象的方法。
由于PriorityQueue().queue不是方法,而是实例属性,因此需要提供一种可以返回该属性值的方法。
下面的示例选择了带有get_attribute子类的通用PriorityQueue方法。

# Python 3.7.1
from queue import PriorityQueue
from multiprocessing.managers import SyncManager
from multiprocessing import Process


SENTINEL = None


class MyPriorityQueue(PriorityQueue):
    def get_attribute(self, name):
        return getattr(self, name)


class MyManager(SyncManager):
    pass


def get_manager():
    MyManager.register("PriorityQueue", MyPriorityQueue)
    m = MyManager()
    m.start()
    return m


def f(q):
    for item in iter(lambda: q.get()[1], SENTINEL):
        print(item)
    print(f'queue: {q.get_attribute("queue")}')


if __name__ == '__main__':

    m = get_manager()
    pq = m.PriorityQueue()

    tasks = enumerate([f'item_{i}' for i in range(5)] + [SENTINEL])

    for task in tasks:
        pq.put(task)

    print(f'queue: {pq.get_attribute("queue")}')
    print(f'maxsize: {pq.get_attribute("maxsize")}')

    p = Process(target=f, args=(pq,))
    p.start()
    p.join()

实际输出

queue: [(0, 'item_0'), (1, 'item_1'), (2, 'item_2'), (3, 'item_3'), (4, 'item_4'), (5, None)]
maxsize: 0
item_0
item_1
item_2
item_3
item_4
queue: []
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值