Source code for simulator.core.DtnLock

# -*- coding: utf-8 -*-

from collections import deque
import simpy
from simulator.core.DtnCore import Simulable


[docs]class DtnLockException(Exception): pass
[docs]class DtnLock(Simulable): """ This class implements a traditional lock in the Simpy world. In this version, there are not priorities. Usage examples: 1) To create the lock: ``lock = DtnLock(env)`` 2) To acquire the lock and block until it is ready: ``yield lock.acquire()`` 3) To release the lock: ``lock.release()`` """ def __init__(self, env): super().__init__(env) # The lock is modeled as resource of capacity 1 self.lock = simpy.Resource(env, capacity=1) # Since the simpy.Resource is FIFO, we can store the # key to all the lock requests into a Python FIFO queue. self.keys = deque() # If true, this is lock is taken self.taken = False def acquire(self): # Acquire the lock and save it in the key queue key = self.lock.request() self.keys.appendleft(key) return key def release(self): try: key = self.keys.pop() self.lock.release(key) except IndexError: raise DtnLockException()
# ============================================================================= # === TESTING Lock # ============================================================================= bundle = 0 def agent(pid, env, lock, produce_rate=10, consume_rate=50): global bundle while True: # Wait for a while yield env.timeout(expovariate(1/produce_rate)) # Create a new bundle bundle += 1 # Print bundle arrival print('t={:.3f}:\tProducer {} wants to transmit bundle {}'.format(env.now, pid, bundle)) # Acquire the lock yield lock.acquire() # Print transmission start print('t={:.3f}:\tProducer {} starts transmission of bundle {}'.format(env.now, pid, bundle)) # Wait while transmission occurs yield env.timeout(expovariate(1/consume_rate)) # Print transmission end print('t={:.3f}:\tProducer {} ends transmission of bundle {}'.format(env.now, pid, bundle)) # Release the lock to let someone else transmit lock.release() if __name__ == '__main__': # Imports for testing from random import expovariate # Initialize constants SIM_TIME = 1000 # Create simulation environment env = simpy.Environment() env.log = True lock = DtnLock(env) # Run simulation environment env.process(agent(1, env, lock)) env.process(agent(2, env, lock)) env.process(agent(3, env, lock)) # Run simulation env.run(until=SIM_TIME)