从某种意义上来说,信号量和线程池很像,他们都会根据你设置的线程上限值来自动帮你管理线程,但是信号量更倾向于‘锁’的概念
先看一个简单的多线程案例:
import threading
import time
def work(name):
print(f'{name}进厕所了')
time.sleep(1)
print(f'{name}出厕所了')
def main_thread():
name = ['张三', '李四', '陈五', '王六', '横七', '竖八', ]
t_l = []
thread = [threading.Thread(target=work, args=(name[i],)) for i in range(5)]
# 启动线程
for t in thread:
t.start()
t_l.append(t)
# 关闭线程
for i in t_l:
i.join()
main_thread()
打印结果:
现在我想把条件改为厕所一次只能进一人该怎么修改代码呢,在之前或许我们只能想到互斥锁一类的限制机制,而现在我们可以用信号量(Semaphore)解决
首先定义全局变量:
import threading
sema = threading.Semaphore(count)
count默认为1,其意义是控制线程访问资源的数量,可以使用acquire()
添加,以及release()
释放,通俗来讲就相当于变量**sema
是厕所,count
就是厕所的坑位,acquire()
一次就是进来一个人,release()
一次就是出去一个人**
def work(name):
# 添加
sema.acquire()
print(f'{name}进厕所了')
time.sleep(1)
# 释放
sema.release()
print(f'{name}出厕所了')
def work(name):
with sema:
sema.release()
print(f'{name}进厕所了')
time.sleep(1)
print(f'{name}出厕所了')
两种写法一样
知晓了信号量的用法那么就可以修改之前的案例了
import threading
import time
sema = threading.Semaphore(1)
def work(name):
with sema:
sema.acquire()
print(f'{name}进厕所了')
time.sleep(1)
print(f'{name}出厕所了')
def main_thread():
name = ['张三', '李四', '陈五', '王六', '横七', '竖八', ]
t_l = []
thread = [threading.Thread(target=work, args=(name[i],)) for i in range(5)]
# 启动线程
for t in thread:
t.start()
t_l.append(t)
# 关闭线程
for i in t_l:
i.join()
main_thread()
结果: