Python线程信号量Semaphore原理与实战应用
本文深入解析Python中threading模块的信号量(Semaphore)机制,通过内置计数器限制同时运行的线程数量。文章详细介绍了acquire()和release()函数的作用,并提供了限制最大并发数为5的完整代码示例及运行结果分析,帮助开发者有效管理多线程资源,避免系统过载。
本文详细解析Python线程信号量(Semaphore)的使用方法,通过具体示例代码展示其核心功能,为读者在学习或实际工作中提供参考价值。
信号量(Semaphore)的基本原理
一、信号量(Semaphore)的基本原理
多线程并发执行能提升程序运行效率,但线程数量并非越多越好。信号量通过内置计数器来限制同时运行的线程数量:当启动线程(消耗信号量)时,计数器自动减一;当线程结束(释放信号量)时,计数器自动加一。若计数器为零,新启动的线程将被阻塞,直到有现有线程结束并释放信号量为止。
信号量相关函数说明
二、信号量相关函数说明
acquire():用于消耗信号量,使内置计数器减一。
release():用于释放信号量,使内置计数器加一。
信号量内部维护一个计数器以控制线程数量。调用acquire()会消耗信号量,计数器自动减一;调用release()会释放信号量,计数器自动加一。当计数器为零时,后续的acquire()调用将被阻塞,直到有线程调用release()释放信号量。
信号量的实际应用
三、信号量的实际应用
以下示例展示了如何创建多个线程,并通过信号量限制同一时间最多运行5个线程:
# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:何以解忧
@Blog(个人博客地址): shuopython.com
@WeChat Official Account(微信公众号):猿说python
@Github:www.github.com
@File:python_semaphore.py
@Time:2019/10/23 21:25
@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!
"""
# 导入线程模块
import threading
# 导入时间模块
import time
# 添加一个计数器,最大并发线程数量5(最多同时运行5个线程)
semaphore = threading.Semaphore(5)
def foo():
semaphore.acquire() #计数器获得锁
time.sleep(2) #程序休眠2秒
print("当前时间:",time.ctime()) # 打印当前系统时间
semaphore.release() #计数器释放锁
if __name__ == "__main__":
thread_list= list()
for i in range(20):
t=threading.Thread(target=foo,args=()) #创建线程
thread_list.append(t)
t.start() #启动线程
for t in thread_list:
t.join()
print("程序结束!")
运行结果如下:
当前时间: Wed Oct 23 22:21:59 2019
当前时间: Wed Oct 23 22:21:59 2019
当前时间: Wed Oct 23 22:21:59 2019
当前时间: Wed Oct 23 22:21:59 2019
当前时间: Wed Oct 23 22:21:59 2019
当前时间: Wed Oct 23 22:22:01 2019
当前时间: Wed Oct 23 22:22:01 2019
当前时间: Wed Oct 23 22:22:01 2019
当前时间: Wed Oct 23 22:22:01 2019
当前时间: Wed Oct 23 22:22:01 2019
当前时间: Wed Oct 23 22:22:03 2019
当前时间: Wed Oct 23 22:22:03 2019
当前时间: Wed Oct 23 22:22:03 2019
当前时间: Wed Oct 23 22:22:03 2019
当前时间: Wed Oct 23 22:22:03 2019
当前时间: Wed Oct 23 22:22:05 2019
当前时间: Wed Oct 23 22:22:05 2019
当前时间: Wed Oct 23 22:22:05 2019
当前时间: Wed Oct 23 22:22:05 2019
当前时间: Wed Oct 23 22:22:05 2019
程序结束!
从打印的日志可以看出,同一时间仅有5个线程在运行。每隔两秒后,系统再次启动5个线程,直到全部20个线程运行结束。如果未设置信号量而直接调用start()启动线程,所有线程的输出时间将几乎一致。这一现象可以通过自行实验验证,原理较为直观。
以上就是本文的全部内容,希望对大家的学习有所帮助,也欢迎大家继续支持本站。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













