Как реализовать не блокирующий менеджер для python многопроцессорной обработки - PullRequest
0 голосов
/ 01 апреля 2020

Я пытаюсь настроить менеджер для нескольких python процессов. Моя установка в настоящее время server процесс, N worker_processes и 1 expensive_item_getter процесс. Я хотел бы, чтобы рабочие процессы запрашивали ресурсы у менеджера, который может занять некоторое время, не блокируя менеджера. Многие из рабочих процессов будут запрашивать одни и те же ресурсы, поэтому они кэшируются в менеджере, но, вероятно, будут запрашивать тот же ресурс до того, как будет обработан первый запрос и результат будет кэширован. Я уверен, что это было сделано раньше, и есть решение, но в настоящее время оно ускользает от меня.

  • В идеале с совместимостью кода для python 3.4+, но не обязательно.
  • Менеджер не должен блокировать дорогие вызовы, но должен в конечном итоге вернуть запрошенный ресурс правильному процессу и любым другим процессам, которые запросили тот же ресурс с начала операции.
  • Должен быть способ сделать это без создание и управление множеством очередей и списков с помощью обратных вызовов вручную.

  • РЕДАКТИРОВАТЬ Я бы рассмотрел другие библиотеки, но должен быть кросс-платформенным

Я попытался изложить свое намерение ниже.


import multiprocessing

def worker_process(manager):#runs in own process
    item = manager.get_expensive_item("item_name") # this part can be, and currently is be blocking in this process


def expensive_item_getter(item_name): # also runs in own process or thread
    #lots of expensive disk io and GPU time
    return item

class MyManager(multiprocessing.managers.BaseManager):

    def __init__(self):
        ##register methods
        pass

    def get_expensive_item(self, item_name):
        if item_is_cached:
            return cached_item
        else:
            item = expensive_item_getter(item_name)  #this part shouldnt block the server process
            cache_item(item)
            return item

1 Ответ

0 голосов
/ 01 апреля 2020

Вы пробовали? синхронизация между процессами в python

Я использовал список блокировок

  if not item_name in self.locks:
    self.locks[item_name ] = Lock()


  with self.locks[item_name]:
    if item_name in cache:
      return cached_item
    else:
      item = expensive_item_getter(item_name)  #this part shouldnt block the server process
      cache_item(item)
      return item

Я никогда не работал с BaseManager, поэтому не знаю, вызовы к себе get_exорого_items блокируют весь менеджер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...