信号量也是一把锁,可以指定信号量为5,对比互斥锁同一时间只能有一个任务抢到锁去执行,信号量同一时间可以有5个任务拿到锁去执行,如果说互斥锁是合租房屋的人去抢一个厕所,那么信号量就相当于一群路人争抢公共厕所,公共厕所有多个坑位,这意味着同一时间可以有多个人上公共厕所,但公共厕所容纳的人数是一定的,这便是信号量的大小
Copy from threading import Thread , Semaphore
import threading
import time
def func ():
sm . acquire ()
print ( ' %s gets sm' % threading. current_thread (). getName ())
time . sleep ( 3 )
sm . release ()
if __name__ == '__main__' :
sm = Semaphore ( 5 )
for i in range ( 23 ):
t = Thread (target = func)
t . start ()
Copy - Semaphore管理一个内置的计数器,如value=5
- 每当调用acquire()时内置计数器-1,调用release() 时内置计数器+1
- 计数器不能小于0,当计数器为0时,acquire()将阻塞线程直到其他线程调用release()
Copy from threading import Event
event . is_set () :返回event的状态值;
event . wait () :如果 event . is_set () == False将阻塞线程
event . set () : 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度
event . clear () :恢复event的状态值为False
例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作
Copy import random
import threading
import time
from threading import Thread , Event
def conn_mysql ():
count = 1
while not event . is_set ():
if count > 10 :
return TimeoutError ( '超时连接' )
print ( '< %s >第 %s 次尝试连接' % (threading. current_thread (). getName (), count))
event . wait ( 0.5 )
count += 1
print ( '< %s >连接成功' % threading. current_thread (). getName ())
def check_mysql ():
print ( '[ %s ]正在检查mysql' % threading. current_thread (). getName ())
time . sleep (random. randint ( 2 , 4 ))
event . set ()
if __name__ == '__main__' :
event = Event ()
event = Event ()
conn1 = Thread (target = conn_mysql)
conn2 = Thread (target = conn_mysql)
check = Thread (target = check_mysql)
conn1 . start ()
conn2 . start ()
check . start ()
Copy from threading import Timer
def hello ():
print ( 'Hello World' )
if __name__ == '__main__' :
t = Timer ( 3 , hello)
t . start ()