简体   繁体   中英

How to implement non blocking manager for python multiprocessing

I am trying to set up a manger for multiple python processes. My setup is currently a server process, N worker_processes and 1 expensive_item_getter process. I would like the worker processes to request resources from the manager that may take some time to acquire, without blocking the manager. Many of the worker processes will request the same resources, and so these are cached in the manager, but will likely request the same resource before the first request has been handled and the result cached. I am sure this has been done before and there is a solution but it is currently eluding me.

  • Ideally with code compatibility for python 3.4+ but not essential.

  • Manager should not block on expensive calls but should eventually return the requested resource to the correct process and any other processes that have requested the same resource since the operation started.

  • There must be a way to do this without manually creating and managing lots of queues and lists with callbacks.

  • EDIT I would consider other libraries but would have to be cross platform compatible

I have tried to outline my intent below.


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

Have you tried ? synchronization-between-processes in python

I have used a list of Locks

  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

I have never worked with BaseManager so i don't know if the calls them selfs to get_expensive_items are blocking the entire manager.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM