Python 多线程编程-05-threading 模块 - Semaphore 和 BoundedSemaphore

目 录

1. Semaphore 信号量介绍

2. threading.Semaphore

2.1 threading.Semaphore 属性和方法

2.1.1 threading.Semaphore 构造方法

2.1.2 threading.Semaphore 属性和方法

2.2 threading.Semaphore 使用示范

2.2.1  使用 threading.Semaphore 控制最多线程数量

2.2.2 threading.Semaphore 使用 with 减少代码量

3. threading.BoundedSemaphore

3.1 BoundedSemaphore 和 Semaphore 的区别

3.2 threading.BoundedSemaphore 属性和方法

3.3 threading.BoundedSemaphore 使用示范


Python 多线程编程目录

Python 多线程编程-01-threading 模块初识

Python 多线程编程-02-threading 模块-锁的使用

Python 多线程编程-03-threading 模块 - Condition

Python 多线程编程-04-threading 模块 - Event

Python 多线程编程-05-threading 模块 - Semaphore 和 BoundedSemaphore

Python 多线程编程-06-threading 模块 - Timer  

Python 多线程编程-07-threading 模块 - Barrier

​​​​​

1. Semaphore 信号量介绍

     泛泛的讲,多进程/线程中的信号量机制,可以理解为有二元组(S,Q),S是整形变量,初值为非负数,Q是一个初始状态为空的等待队列,这个机制设计就是为了为了实现进程/线程中同步和互斥关系。

    有同学可能没有接触过 Semaphore 信号量的概念,可以简单参考这篇文章。

​​​​​​2.4 CPU管理--信号量和PV操作_一分耕耘一分收获-CSDN博客。虽然这篇文字是针对进程讲的,但是在多线程编程中,信号量的设计意图和使用机制是一样的。

2. threading.Semaphore

      threading.Semaphore 可以理解为一个内置的计数器,当调用 acquire 方法时候内置计数器 -1,对应着申请资源;调用 release 方法时候内置计数器+1,对应着释放可用资源。

2.1 threading.Semaphore 属性和方法

2.1.1 threading.Semaphore 构造方法

         s=threading.Semaphore(value=1),value 指示信号量的最大计数,默认是1;在代码设计中可以理解为可用资源数目。

2.1.2 threading.Semaphore 属性和方法

threading.Semaphore 属性和方法
序号属性和方法描述
1

acquire(self, blocking=True,

timeout=None)

获得一个信号量,其内置计数器 -1;

如果调用时候不使用参数:如果调用时候计数器大于 0 则 -1 且立刻返回;如果是零时,则阻塞当前线程,等待其他线程调用release() 来释放资源使其大于零。这些是通过适当的交互锁来完成的,因此如果多个acquire() 调用被阻止,release() 将只唤醒其中一个调用。实现可能会随机选择一个,因此哪些被阻塞的线程被唤醒是不可靠的,在这种情况下没有返回值。

如果调用时候使用参数:

a) blocking=True 和上面一致,成功时候立刻返回 True

b) blocking=False,那么计数器是零时候,不会阻塞,而是立刻返回 False。

c) timeout=n,而不等于 None,那么最多阻塞 n 秒,n 秒内没有获得信号量,则返回 False

2mro()内置的 mro 方法,返回类型的方法解析顺序。
3release(self)释放资源,信号量的计数器 +1,如果原来信号量计数器等于0,那么则唤醒一个等待中的线程。

2.2 threading.Semaphore 使用示范

2.2.1  使用 threading.Semaphore 控制最多线程数量

下面设计了一个程序,semaphore 设计了最多5个线程可以同时启动,第n个线程 sleep n-1 秒,然后再 release 资源;这样可以看到在第一秒同时启动了 6 个线程(第一个线程立刻释放,所以第六个立刻获得了资源),接下来则是每隔一秒钟有一个线程获得资源。

import threading
import time

s=threading.Semaphore(5)
thread_list=[]

def fun(n):
    s.acquire()
    print(time.ctime(),"===>",n)
    time.sleep(n)
    s.release()
    
for tmp in range(10):
    t=threading.Thread(target=fun,args=(tmp,))
    thread_list.append(t)

for tmp in range(10):
    thread_list[tmp].start()

运行结果如下:

2.2.2 threading.Semaphore 使用 with 减少代码量

使用 with 用法,可以省去 release() 方法,结果是一样的。

s=threading.Semaphore(5)
thread_list=[]

def fun2(n):
    with s:
        print(time.ctime(),"===>",n)
        time.sleep(n)
    
for tmp in range(10):
    t=threading.Thread(target=fun2,args=(tmp,))
    thread_list.append(t)

for tmp in range(10):
    thread_list[tmp].start()

for tmp in range(10):
    thread_list[tmp].join()
    
print("All done!")

运行结果如下:

3. threading.BoundedSemaphore

3.1 BoundedSemaphore 和 Semaphore 的区别

     BoundedSemaphore 和 Semaphore 的区别的区别在于 threading.BoundedSemaphore 会在过多的使用 release() 时候报错 " ValueError: Semaphore released too many times "。

3.2 threading.BoundedSemaphore 属性和方法

        threading.BoundedSemaphore 的属性和方法和 threading.Semaphore 非常类似,不再赘述。

3.3 threading.BoundedSemaphore 使用示范

代码设计如下,当对 threading.BoundedSemaphore 重复释放时候,就是会报错。

s=threading.Semaphore(3)
bs=threading.BoundedSemaphore(3)
thread_list=[]

def fun(n):
    with s:
        print(time.ctime(),"===>",n)
        time.sleep(n)
    # 即使使用了 with 语句会自动 release,也再显示的释放一次
    s.release() 
    
def fun2(n):
    with bs:
        print(time.ctime(),"===>",n)
        time.sleep(n)
    bs.release()
    
for tmp in range(5):
    t=threading.Thread(target=fun,args=(tmp,))
    thread_list.append(t)

for tmp in range(5):
    thread_list[tmp].start()

# 
thread_list=[]  
time.sleep(6)

for tmp in range(5):
    t=threading.Thread(target=fun2,args=(tmp,))
    thread_list.append(t)

for tmp in range(5):
    thread_list[tmp].start()
    
print("All done!")

运行结果

'''

要是大家觉得写得还行,麻烦点个赞或者收藏吧,想个博客涨涨人气,非常感谢!

'''

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

江南野栀子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值