一、信号量
1 '''100人上厕所的故事'''
2 import time
3 import threading
4 class MyThread(threading.Thread):
5 def run(self):
6 if semaphore.acquire(): #上锁
7 print(self.name)
8 time.sleep(3)
9 semaphore.release() #开锁
10
11 if __name__ == '__main__':
12 semaphore = threading.BoundedSemaphore(5) #创建信号量锁
13 thrs = []
14 for i in range(32):
15 thrs.append(MyThread()) #创建线程
16 for t in thrs:
17 t.start() #开启线程
18
19 '''注释:1.虽然存在GIL锁,Cpython翻译器同时只能执行一个线程。
20 但当正在执行的线程阻塞时,另一条线程马上被执行,多线程并发效果就被体现出来。
21 2.信号量也是一把锁,用来设置同一时间可以并发的线程数。
22 例如:当设置信号量为5时,意味着同一时间只有5条线程可以参与并发执行。
23 就好比100个人去上厕所,但只有5个坑;同一时间只有5个人在放肆,当有空缺时,后面的人补上。
24 3.上述过程不排队,谁先抢到坑位就先执行谁'''
二、条件变量
1 '''吃包子的故事'''
2 import time
3 import threading
4 from random import randint
5 class producer(threading.Thread):
6 def run(self):
7 global L
8 while True:
9 val = randint(0,100) #生成0-100的随机数
10 print('生产者',self.name,'做出了%s号包子' %str(val))
11 if lock_con.acquire(): #上锁
12 L.append(val) #把做出来的包子加入L列表
13 print('笼屉里有以下包子:',L)
14 lock_con.notify() #当L中有包子时,通知waiting的线程启动
15 lock_con.release() #开锁
16 time.sleep(3) #生产者每3秒做一个包子
17 class consumer(threading.Thread):
18 def run(self):
19 global L
20 while True:
21 lock_con.acquire() #上锁
22 if len(L) == 0:
23 lock_con.wait() #L中没包子,条件不满足,自动开锁阻塞并等待通知......。等到通知以后,返回去从上锁开始执行
24 print('消费者',self.name,'吃掉了%s号包子' %str(L[0]))
25 del L[0]
26 print('笼屉里还有的包子为:',L)
27 lock_con.release()
28 time.sleep(1) #消费者每1s吃掉一个包子
29
30 if __name__ == '__main__':
31 L = []
32 lock_con = threading.Condition() #创建条件变量锁
33 threads = []
34 for i in range(3):
35 threads.append(producer()) #创建了3个生产者线程
36 threads.append(consumer()) #创建了1个消费者线程
37 for t in threads:
38 t.start() #启动所有线程,一共4个
39 for t in threads:
40 t.join()
三、同步条件event
1 '''加班的故事'''
2 import threading,time
3 class Boss(threading.Thread):
4 def run(self):
5 print('Boss:今晚加班到10点')
6 event.set() #设置event状态值为True,等待池的线程就绪
7 time.sleep(5)
8 print('Boss:到10点了')
9 event.set()
10 class worker(threading.Thread):
11 def run(self):
12 event.wait() #如果event状态值为False,线程阻塞
13 print('唉,万恶的剥削没人管啊....')
14 event.clear() #设置状态值为False
15 event.wait()
16 print('终于可以回家了,OhYeah!')
17 if __name__ == '__main__':
18 event = threading.Event()
19 threads = []
20 for i in range(5):
21 threads.append(worker())
22 threads.append(Boss())
23 for t in threads:
24 t.start()
25 for t in threads:
26 t.join()