Random stuff, testing things, and so on.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

76 lines
2.1 KiB

"""Resource Manager."""
import logging
import time
from threading import Condition
from threading import Lock
from threading import Thread
LOGGER = logging.getLogger(__name__)
class Resource:
def __init__(self, manager, resources: int):
self._manager = manager
self._resources = resources
def release(self):
LOGGER.debug("Resource of %d will be returned", self._resources)
self._manager.release(self._resources)
@property
def resources(self):
return self._resources
class ResourceManager:
def __init__(self, total_resources: int):
self._total_resources = total_resources
self._cond = Condition(Lock())
LOGGER.debug("Created a manager with %d resources", self._total_resources)
def grab(self, resources: int):
"""Grab a number of resources; if there are not enough resources
available, blocks till they become available.
"""
LOGGER.debug("Requesting %d resources; %d avaialble", resources, self._total_resources)
with self._cond:
self._cond.wait_for(lambda : self._total_resources >= resources)
self._total_resources -= resources
return Resource(self, resources)
def release(self, resources: int):
"""Return the number of resources to the pool."""
with self._cond:
self._total_resources += resources
self._cond.notify()
LOGGER.debug("%d resources returned, %d available", resources, self._total_resources)
def worker(pid, resources):
LOGGER.debug("Thread %d is holding %d resources", pid, resources.resources)
time.sleep(10)
LOGGER.debug("Thread %d finished, releasing %d resources", pid, resources.resources)
resources.release()
def main():
logging.basicConfig(level=logging.DEBUG)
manager = ResourceManager(10)
threads = []
for i in range(10):
resources = manager.grab(i+1)
w = Thread(target=worker, args=[i, resources])
threads.append(w)
w.start()
for t in threads:
t.join()
if __name__ == '__main__':
main()