Skip to content

Instantly share code, notes, and snippets.

@alan-w-255
Created May 20, 2017 07:48
Show Gist options
  • Save alan-w-255/d3c4f759f666e407a441557ef0438a0b to your computer and use it in GitHub Desktop.
Save alan-w-255/d3c4f759f666e407a441557ef0438a0b to your computer and use it in GitHub Desktop.
import threading
import random
import time
num_of_head_north = 0
num_of_head_south = 0
counter_lock = threading.Lock()
bridge_cond = threading.Condition()
bridge_sem = threading.BoundedSemaphore(3)
class car(threading.Thread):
def __init__(self, car_id, direction):
threading.Thread.__init__(self)
self.direction = direction
self.car_id = car_id
def run(self):
if self.direction == 1: # 1 表示方向向南
self.cross_bridge_to_south()
elif self.direction == 0: # 0 表示方向向北
self.cross_bridge_to_north()
def cross_bridge_to_north(self):
global num_of_head_north
global num_of_head_south
counter_lock.acquire()
if num_of_head_south != 0: # 如果有向南走的车, 就等待
counter_lock.release()
bridge_cond.acquire()
bridge_cond.wait()
bridge_cond.release()
while True:
counter_lock.acquire()
if num_of_head_south == 0:
num_of_head_north += 1
counter_lock.release()
break
else:
counter_lock.release()
bridge_cond.acquire()
bridge_cond.wait()
bridge_cond.wait()
else:
num_of_head_north += 1 # 桥上的车数加一
counter_lock.release()
bridge_sem.acquire() # 获取上桥资格
print(">>> on the bridge ", str(self.car_id))
counter_lock.acquire()
num_of_head_north -= 1 # 桥上的车数减一
print(">>>>> leave the bridge", str(self.car_id))
bridge_sem.release() # 释放上桥资源
if num_of_head_north == 0: # 如果桥上向北走的车数为零, 唤醒所有向南走的车。
bridge_cond.acquire()
bridge_cond.notifyAll()
bridge_cond.release()
counter_lock.release()
else:
counter_lock.release()
def cross_bridge_to_south(self):
global num_of_head_north
global num_of_head_south
counter_lock.acquire()
if num_of_head_north != 0: # 如果有向北走的车, 等待
counter_lock.release()
bridge_cond.acquire()
bridge_cond.wait()
bridge_cond.release()
while True:
counter_lock.acquire()
if num_of_head_north == 0:
num_of_head_south += 1
counter_lock.release()
break
else:
counter_lock.release()
bridge_cond.acquire()
bridge_cond.wait()
bridge_cond.release()
else:
num_of_head_south += 1
counter_lock.release()
bridge_sem.acquire() # 获得上桥的资源
print("<-<-<- on the bridge ", str(self.car_id))
counter_lock.acquire()
num_of_head_south -= 1
print("<-<-<-<-<- leave the bridge ", str(self.car_id))
bridge_sem.release() # 释放上桥的资源
if num_of_head_south == 0: # 如果桥上向南走的车数为零, 唤醒等待向北走的。
bridge_cond.acquire()
bridge_cond.notifyAll()
bridge_cond.release()
counter_lock.release()
else:
counter_lock.release()
def main():
cars = []
random.seed()
for x in range(20):
cars.append(car(x, random.randint(0,1)))
for x in cars:
x.start()
for x in cars:
x.join()
print("all cars has gone")
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment