class LightswitchObj:
  def __init__(self):
    self.count = 0
    self.mutex = Semaphore(1)

  def lock(self, semaphore):
    self.mutex.wait()
    self.count += 1
    if self.count == 1:
      semaphore.wait()
    self.mutex.signal()

  def unlock(self, semaphore):
    self.mutex.wait()
    self.count -= 1
    if self.count == 0:
      semaphore.signal()
    self.mutex.signal()
# turnstile

# desired: (all rendezvous) < (all critical points)

from sync import Thread, Semaphore, watcher

N_THREADS = 10
count = 0
mutex = Semaphore(1)
turnstile = Semaphore(0)


def child(i):
    global count
    print(str(i) + "rendezvous")
    mutex.wait()
    count += 1
    mutex.signal()
    if count == N_THREADS:
        turnstile.signal()
    turnstile.wait()
    turnstile.signal()
    print(str(i) + "critical point")

    # note that the turnstile is _not_ ready to go again: it has a value of 1


watcher()

[Thread(child, i) for i in range(N_THREADS)]
# readers writers

# desired: n readers can all simultaneously read a value but only 1 writer can write
# no readers can be reading while writing is happening

# note that there's a tendency for starvation to occur unless you tune the sleeps properly
from sync import Thread, Semaphore, watcher
import time, random

N_READERS = 5
N_WRITERS = 5

value = 0
readers = 0
mutex = Semaphore(1)
roomEmpty = Semaphore(1)

def writer(i):
  global value
  while True:
    time.sleep(random.random())
    roomEmpty.wait()
    value = random.randint(0,5)
    print("Writer %d is writing %d" % (i, value))
    time.sleep(random.random() * 3)
    roomEmpty.signal()

def reader(i):
  global value
  global readers
  while True:
# barrier

# desired: (all rendezvous) < (all critical point)

# suboptimal because the last task probably is the lowest-priority task, so this involves a lot of context switches
from sync import Thread, Semaphore, watcher

N_THREADS = 10
count = 0
mutex = Semaphore(1)
barrier = Semaphore(0)


def child(i):
    global count
    print(str(i) + "rendezvous")
    mutex.wait()
    count += 1
    if count == N_THREADS:
        for j in range(N_THREADS):
            barrier.signal()
    mutex.signal()
    barrier.wait()
    print(str(i) + "critical point")

    # note that the barrier is ready to go again


watcher()

[Thread(child, i) for i in range(N_THREADS)]
Example #5
0
# multiplex

# desired: up to NUM_SIMULTANEOUS "critical point" at once

from sync import Thread, Semaphore, watcher

NUM_SIMULTANEOUS = 3
multiplex = Semaphore(NUM_SIMULTANEOUS)


def child(i):
    print(str(i) + "a")
    multiplex.wait()
    print(str(i) + "critical point")
    multiplex.signal()
    print(str(i) + "c")


watcher()

[Thread(child, i) for i in range(10)]
Example #6
0
# producer-consumer with fixed buffer size

# desired: producer sends an event every so often
# if nothing is in the queue consumer should wait
# block on the producer side if we're out of buffer spaces

from sync import Thread, Semaphore, watcher
import time, random
from collections import deque

BUFFER_SIZE = 3

mutex = Semaphore(1)
items = Semaphore(0)
spaces = Semaphore(BUFFER_SIZE)
buffer = deque()

t0 = time.time()


class Event:
    def __init__(self, x):
        self.x = x


def producer():
    global buffer
    i = 0
    while True:
        time.sleep(1)
        event = Event(i)
Example #7
0
# cowboys

# desired: group of cowboys eat dinner from a large pot with M servings of chili
# cowboy wants to eat, he helps himself from pot
# if pot empty, cowboy wakes up the cook then waits until cook refills the pot

from sync import Thread, Semaphore, watcher
import time, random

N_COWBOYS = 10
M = 15

t0 = time.time()

servings = 0
mutex = Semaphore(1)
emptyPot = Semaphore(0)
fullPot = Semaphore(0)

def cowboy(i):
  global servings
  while True:
    mutex.wait()
    if servings == 0:
      print("[%f] Cowboy %d is asking cook to refill pot" % (time.time() - t0, i))
      emptyPot.signal()
      fullPot.wait()
      servings = M
    servings -= 1
    time.sleep(random.random()) # it takes up to 1s to take a serving
    print("[%f] Cowboy %d took a serving with %d servings left" % (time.time() - t0, i, servings))
Example #8
0
# desired: "b" then "a"

from sync import Thread, Semaphore, watcher

sem = Semaphore(0)


def child1():
    sem.wait()
    print("child a")


def child2():
    print("child b")
    sem.signal()


watcher()

threada = Thread(child1)
threadb = Thread(child2)
# producer-consumer

# desired: producer sends an event every so often
# if nothing is in the queue consumer should wait

from sync import Thread, Semaphore, watcher
import time, random
from collections import deque

mutex = Semaphore(1)
items = Semaphore(0)
buffer = deque()

class Event:
  def __init__(self, x):
    self.x = x

def producer():
  global buffer
  i = 0
  while True:
    time.sleep(random.random() * 5)
    event = Event(i)
    print("Producing event %d!" % event.x)
    mutex.wait()
    buffer.append(event)
    mutex.signal()
    items.signal()
    i += 1

def consumer():
Example #10
0
# readers writers using lightswitches avoiding starvation

# desired: n readers can all simultaneously read a value but only 1 writer can write
# no readers can be reading while writing is happening

from sync import Thread, Semaphore, watcher
from LightswitchObj import LightswitchObj
import time, random

N_READERS = 5
N_WRITERS = 5

value = 0
lightswitch = LightswitchObj()
roomEmpty = Semaphore(1)
turnstile = Semaphore(1)


def writer(i):
    global value
    while True:
        time.sleep(random.random())
        turnstile.wait()
        roomEmpty.wait()
        value = random.randint(0, 5)
        print("Writer %d is writing %d" % (i, value))
        time.sleep(random.random() * 3)
        turnstile.signal()
        roomEmpty.signal()

Example #11
0
# rendezvous

# desired: (a1 and b1) < (a2 and b2)

from sync import Thread, Semaphore, watcher

sem1 = Semaphore(0)
sem2 = Semaphore(0)


def child1():
    print("a1")
    sem1.signal()
    sem2.wait()
    print("a2")


def child2():
    print("b1")
    sem2.signal()
    sem1.wait()
    print("b2")


watcher()

threada = Thread(child1)
threadb = Thread(child2)
 def __init__(self, n):
     self.N_THREADS = n
     self.count = 0
     self.mutex = Semaphore(1)
     self.turnstile = Semaphore(0)
     self.turnstile2 = Semaphore(0)
class Barrier:
    def __init__(self, n):
        self.N_THREADS = n
        self.count = 0
        self.mutex = Semaphore(1)
        self.turnstile = Semaphore(0)
        self.turnstile2 = Semaphore(0)

    def phase1(self):
        self.mutex.wait()
        self.count += 1
        if self.count == self.N_THREADS:
            for j in range(self.N_THREADS):
                self.turnstile.signal()
        self.mutex.signal()
        self.turnstile.wait()

    def phase2(self):
        self.mutex.wait()
        self.count -= 1
        if self.count == 0:
            for j in range(self.N_THREADS):
                self.turnstile2.signal()
        self.mutex.signal()
        self.turnstile2.wait()

    def wait(self):
        self.phase1()
        self.phase2()
# dining philosophers

# desired: n philosophers, each of whom require left and right chopsticks, must eat
# this induces deadlock

from __future__ import print_function
from sync import Thread, Semaphore, watcher
import time, random

N_PHILOSOPHERS = 5

chopsticks = [Semaphore(1) for i in range(N_PHILOSOPHERS)]

# chopsticks_used is just for illustration purposes and isn't part of the solution
chopsticks_used = [False for i in range(N_PHILOSOPHERS)]
mutex_chopsticks_used = Semaphore(1)


def print_chopstick(chopstick):
    if chopstick: return "X"
    else: return "O"


def left(i):
    return i


def right(i):
    return (i + 1) % N_PHILOSOPHERS

Example #15
0
# readers writers using lightswitches

# desired: n readers can all simultaneously read a value but only 1 writer can write
# no readers can be reading while writing is happening

# note that there's a tendency for starvation to occur unless you tune the sleeps properly
from sync import Thread, Semaphore, watcher
from LightswitchObj import LightswitchObj
import time, random

N_READERS = 5
N_WRITERS = 5

value = 0
lightswitch = LightswitchObj()
roomEmpty = Semaphore(1)


def writer(i):
    global value
    while True:
        time.sleep(random.random())
        roomEmpty.wait()
        value = random.randint(0, 5)
        print("Writer %d is writing %d" % (i, value))
        time.sleep(random.random() * 3)
        roomEmpty.signal()


def reader(i):
    global value
 def __init__(self):
   self.count = 0
   self.mutex = Semaphore(1)
Example #17
0
# mutex

# desired: count always 2 at end

# note that because python, you don't really need a mutex because python only simulates multiple threads
# however this is just to show the concept

from sync import Thread, Semaphore, watcher

mutex = Semaphore(1)
count = 0


def child1():
    global count
    mutex.wait()
    print("a1")
    count += 1
    mutex.signal()


def child2():
    global count
    mutex.wait()
    print("b1")
    count += 1
    mutex.signal()


watcher()