Created
November 17, 2011 07:04
-
-
Save ejamesc/1372562 to your computer and use it in GitHub Desktop.
Semaphore PS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
This simulation program works as follows: | |
The Task class contains a list of tasks to run, and tracks block state. | |
The Task.next() function exposes the next function of the generator tasks it contains. | |
When a block is called (via Task.block(name_of_task)) all other tasks except for | |
name_of_task will be added to the internal Task blocklist. | |
Task.next() will skip over any tasks currently on the blocklist | |
during Round-Robin iteration. | |
Task.release_block() clears the block list, thus allowing all other tasks to continue running | |
""" | |
class Semaphore(): | |
"""Semaphore class, uses an empty list to keep track of resources | |
""" | |
def __init__(self): | |
self.items = [] | |
self.MAX_AVAILABLE = 1 # can be whatever number of resources | |
self.available = self.MAX_AVAILABLE | |
def acquire(self, x, task): | |
self.items.append({x: task}) | |
def release(self, x, task): | |
if [x, task] in items: | |
self.items.remove({x: task}) | |
def is_acquired(self, x): | |
return True if x in self.items else False | |
class Task(): | |
"""Task class, maintains block state | |
""" | |
def __init__(self): | |
self.gens = [] | |
self.blocklist = [] | |
def __init__(self, funclist): | |
self.gens = funclist | |
self.blocklist = [] | |
def add(self, task): | |
self.gens.append(task) | |
def block(self, task): | |
self.blocklist = list(self.gens) # python clone list syntax | |
self.blocklist.remove(task) | |
def release_block(self): | |
self.blocklist = [] | |
def next(self): | |
"""Round robin generator | |
""" | |
temp = self.gens[0] | |
self.gens.remove(temp) | |
self.gens.append(temp) | |
if temp in self.blocklist: | |
yield | |
else: | |
try: | |
yield temp.next() | |
except StopIteration: | |
# if task has ended, yield | |
yield | |
for x in self.next(): | |
yield x | |
def task1(x): | |
reg = x[0] | |
print '1-1' | |
yield | |
reg = reg+1 | |
print '1-2' | |
yield | |
sema.acquire(x[0]) | |
x[0] = reg | |
#release(x[0]) | |
print '1-3' | |
yield | |
def task2(x): | |
reg = x[0] | |
print '2-1' | |
yield | |
reg = reg+1 | |
print '2-2' | |
yield | |
x[0] = reg | |
print '2-3' | |
yield | |
def scheduler(): | |
x=[0] | |
taskfunc1 = task1(x) | |
taskfunc2 = task2(x) | |
tasker = Task([taskfunc1,taskfunc2]) | |
for i in range(2): | |
next(tasker.next()) | |
tasker.block(taskfunc1) #taskfunc1 is now blocking | |
for i in range(3): | |
next(tasker.next()) | |
tasker.release_block() #other tasks apart from taskfunc1 may now run. | |
for i in range(3): | |
next(tasker.next()) | |
print "x=", x[0] | |
# This is the main program, to demonstrate | |
sema = Semaphore() | |
scheduler() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment