Julio Biason
2 years ago
1 changed files with 75 additions and 0 deletions
@ -0,0 +1,75 @@
|
||||
"""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() |
Loading…
Reference in new issue