########################################## A Description: I approached the problem as a modified readers/writer problem. However, firstly the turnstile is not good enough. Semaphores do not guarantee first-in-first-out. But, we can declare our own version that does. The turnstile also guarantees one-at-a-time access to getting on the rope. If the baboon in the turnstile (crossing next) is moving opposite the current flow, the baboons that have already made it through the turnstile (either waiting to cross or crossing) will be allowed to finish, but no more will join them (fifo, and we have an opposite-traveler next). This in-turnstile opposite-travel blocking is accomplished by the Lightswitch operating on the [east/west]OnRope Semaphores. The first baboon on the rope sets the flow. If he's followed (chronologically) by others going the same way, the multiplex allows a certain amount of them on at a time. When a Baboon has crossed the rope, it unlocks the LightSwitch. The last one across unblocks the opposite-traveling Baboon restriction in the turnstile. If there is an opposite-traveler, he proceeds and resets the flow in his direction. This solution is inefficient in that if Baboons arrive chronologically in alternating directions the rope will only ever carry one baboon at a time. ########################################## # This class will be defined in pseudo Java style since I'm more comfortable with Java than python # A lightswitch - pretty much straight out of the book Class LightSwitch{ private int count; public LightSwitch(Semaphore s){ mySemp = s; count = 0; } public void lock(){ mutex.wait(); count++; if(count==1) mySem.wait(); mutex.signal(); } public void unlock(){ mutex.wait(); count--; if(count == 0) mySem.signal(); mutex.signal(); } }; ########################################## # This class will be defined in pseudo Java style since I'm more comfortable with Java than python # A concurrent FIFO - pretty much straight out of the book Class Fifo { private Queue queue = new Queue(); private Semaphore mutex = new Semaphore(1); public wait(Semaphore sem){ mutex.wait(); queue.add(sem); mutex.signal(); sem.wait(); } public signal(){ mutex.wait(); Semaphore s = queue.remove(); mutex.signal(); sem.signal(); } }; ########################################## # And I switch back into python-ish code # GLOBALS: int MAX_BABOONS_ON_ROPE = 5 rope = Semaphore(MAX_BABOONS_ON_ROPE) eastOnRope = Semaphore(1) westOnRope = Semaphore(1) eastSwitch = LightSwitch(eastOnRope) westSwitch = LightSwitch(westOnRope) turnstile = Fifo() # I had some doubts about Python/Java/etc so I'm probably going to get myself into trouble here: local mySem = Semaphore(0) # This is a semaphore that belongs only to a single thread. Each thread has its own ########################################## # EASTSIDER CODE turstile.wait(mySem) westOnRope.wait() eastSwitch.lock() turnstile.signal() westOnRope.signal() rope.wait() cross() rope.signal() # Last one across lets the westsiders cross eastSwitch.unlock() ########################################## # WESTSIDER CODE turstile.wait(mySem) eastOnRope.wait() westSwitch.lock() turnstile.signal() eastOnRope.signal() rope.wait() cross() rope.signal() # Last one across lets the eastsiders cross westSwitch.unlock()