信号量:semaphore
信号量是用来控制线程并发数的。(理解:虽然GIL任意时刻都只有一个线程被执行,但是所有线程都有资格去抢,semaphore就是用来控制抢的GIL的数量,只有获取了semaphore的线程才有资格去抢GIL,起到了限制线程并发数的作用)
import threading
import time class MyThread(threading.Thread):
def run(self):
if semap.acquire():
print(semap)
print(self.name)
time.sleep(5)
semap.release() semap = threading.Semaphore(5) # 括号内如果没有指定数据,默认为1 thrs = [] for i in range(100):
thrs.append(MyThread())
for i in thrs:
i.start()
semaphore也是一把锁,这把锁内部有一个计数器,被acquire()的时候-1,release()的时候+1,当计数器为0的时候,其它线程将被阻塞。
semaphore和RLock都可以被重复获取,也都有计数器,区别是:semaphore是被不同线程获取,而RLock只能被同一线程重复获取。
条件变量:不仅能实现锁的功能,而且能够实现类似线程间的通信功能
用于一个标志符来实现线程间通信
threading.Condition([Lock/Rlock]):锁是可选选项,不传入锁,对象自动创建一个Rlock(0
wait():条件不满足时调用,线程会释放锁并进入等待阻塞
notify():条件创造后调用,通知等待池激活一个线程
notifyAll():条件创造后调用,通知等待池激活所有线程
import threading
from random import randint
import time class Producer(threading.Thread):
def run(self):
global L
while 1:
lock_con.acquire()
r = randint(0, 100)
print(self.name + "已生产" + str(r))
L.append(r)
lock_con.notify()
lock_con.release()
time.sleep(1) class Consumer(threading.Thread):
def run(self):
global L
while 1:
lock_con.acquire()
if len(L) == 0:
lock_con.wait()
print("消费者吃了"+str(L[0]))
del L[0]
lock_con.release() if __name__ == '__main__':
L = []
lock_con = threading.Condition()
threads = []
for i in range(5):
threads.append(Producer())
threads.append(Consumer())
for i in threads:
i.start()
要想实现两个线程之间的通信,两个线程用的必须是同一把锁,不然无法起到作用。
条件同步(Event)
条件同步和条件变量同步差不多,只是少了锁的功能,因为条件同步设计于不访问共享资源的环境。
event = threading.Event():条件环境变量,初始值为False
event.isSet():返回event的状态值
event.set():设备event的状态值为True,所有阻塞池的线程激活进入就绪状态,等待操作系统调试。
event.clear():设置event的状态值为False
event.wait():如果event的状态值为False时,阻塞线程
实例1:
import threading
import time class Boss(threading.Thread):
def run(self):
print("今晚要加班!!!!")
event.set()
time.sleep(5)
print("已经10点了,可以下班了!")
event.set() class Work(threading.Thread):
def run(self):
event.wait()
print("命苦啊!!!!")
event.clear()
event.wait()
print("oh,yeah!") if __name__ == '__main__':
event = threading.Event()
threads = []
for i in range(3):
threads.append(Work())
threads.append(Boss())
for i in threads:
i.start()
for i in threads:
i.join()
实例2:红绿灯
import threading
import time
import random def ligth():
if not event.isSet():
event.set()
count = 0
while 1:
if count < 10:
print("this light is green!")
elif count < 13:
print("the light is yellow!")
elif count < 20:
if event.isSet():
event.clear()
print("the light is red!")
else:
count = 0
event.set()
time.sleep(1)
count += 1 def car(n):
while 1:
time.sleep(random.randrange(10))
if event.isSet():
print("car %s is running" % n)
else:
print("car %s is waiting for red light..." % n) event = threading.Event()
Light = threading.Thread(target=ligth)
Light.start()
for i in range(3):
t = threading.Thread(target=car,args=(i,))
t.start()