Created
May 20, 2017 07:48
-
-
Save alan-w-255/d3c4f759f666e407a441557ef0438a0b to your computer and use it in GitHub Desktop.
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
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