функция очереди для многопроцессной приоритетной очереди в python с классом SyncManager - PullRequest
0 голосов
/ 04 декабря 2018

Я хотел реализовать приоритет многопроцессорной обработки.Я нашел этот ответ: - Странное поведение Queue.PriorityQueue с многопроцессорной обработкой в ​​Python 2.7.6

от Dano

После того, как я это реализовал.Я мог бы использовать функции .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'

Я прочитал документацию по Python для SyncManager и изменил свой код.

Новый код: -

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 функции register, чтобы отобразить тип возвращаемого значения функций, упомянутых в exposed, но я не знаюкак это использовать.

Может ли кто-нибудь помочь мне с этим, чтобы я мог печатать элементы очереди, не выталкивая их из очереди

1 Ответ

0 голосов
/ 05 декабря 2018

Вы можете использовать только методы референта через прокси.Поскольку 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: []
...