Python之信号量
什么是信号量
信号量详解
案例
什么是信号量
从某种意义上来说,信号量和线程池很像,他们都会根据你设置的线程上限值来自动帮你管理线程,但是信号量更倾向于‘锁’的概念
- 信号量是一种并发控制机制,用于限制对共享资源的并发访问数量。通过控制信号量的计数器,可以允许多个线程或进程同时访问一定数量的资源。信号量常用于解决生产者-消费者问题、限流等场景。
- 线程池是一组预先创建的线程集合,用于执行任务队列中的任务。线程池管理了可复用的线程,并根据需要分配任务给空闲的线程进行处理。线程池提供了更好的线程管理、调度和性能优化,适用于大量短期任务的并发处理。
信号量详解
先看一个简单的多线程案例:
import threading
import timedef 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 threadingsema = 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 timesema = 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()
结果: