首页 > 其他分享 >多线程开发 使用Semaphore和BoundedSemaphore对象

多线程开发 使用Semaphore和BoundedSemaphore对象

时间:2023-07-18 16:37:49浏览次数:40  
标签:BoundedSemaphore Semaphore 信号量 计数器 线程 semaphore 多线程

多线程开发 使用Semaphore和BoundedSemaphore对象

一、使用Semaphore和BoundedSemaphore对象

在Python中,可以使用Semaphore和BoundedSemaphore来控制多线程信号系统中的计数器。

1. Semaphore

在Python程序中,类threading.Semaphore是一个信号机,控制着对公共资源或者临界区的访问。信号机维护有一个计数器,指定可同时访问资源或者进入临界区的线程数。每次有一个线程获得信亏机时,计数器为-1。若计数器为0,其他线程就停止访问信号机,,直到另一个线程释放信号机。

在对象 Semaphore中,主要包含了如下所示的内置方法:

(1) aquire(blocking = True,timeout = None): 用于获取Semaphore对象。

  • 当使用默认参数(blocking = True)调用本方法时,如果内部计数器的值大于零,将之减一,并返回;如果等于零,则阻塞,并等待其他线程调用release()方法以使计数器为正。这个过程有严格的互锁机制控制,以保证如果有多条线程正在等待解锁,release()调用只会唤醒其中一条线程。唤醒哪一条是随机的。本方法返回True,或无限阻塞。
  • 如果blocking = False,则不阻寒,但若获取失败的话,返回False。
  • 当设定了timeout参数时,最多阻塞timeout秒,如果超时,返回False。

(2) release():用于释放Semaphore,给内部计数器加1,可以唤醒处于等待状态的线程。

  • 在使用计数器对象Semaphore时,调用acquire()会使这个计数器减1,调用release()会使这个计数器加1。
  • 计数器的值永远不会小于0,当计数器到0时,再调用acquire()就会阻塞,直到其他线程来调用release()为止。

例如在下面的实例中,演示了使用Semaphore对象运行4个线程的过程。

import threading
import time


def func(semaphore: threading.Semaphore, num):
    # 获得信号量,信号量 -1
    semaphore.acquire()
    print(f"打印信号量:第{num}次")
    time.sleep(3)

    # 释放信号量,信号量 +1
    semaphore.release()


if __name__ == '__main__':
    # 初始化信号量,数量为 2
    semaphore = threading.Semaphore(2)
    # 运行4个线程
    for num in range(4):
        t = threading.Thread(target=func, args=(semaphore, num))
        t.start()

2. BoundedSemaphore

在pyhon程序中,类threading.BoundSemaphore用于实现BoundedSemaphore对象。BoundedSemaphore会检查内部计数器的值,并保证它不会大于初始值,如果超过就会引发一个ValueError错误。在大多数情况下,BoundedSemaphore用于守护限制访问(
但不限于1)的资源,如果semaphore被release()过多次,这意味着存在在bug。

对象BoundedSemaphore会返回一个新的有界信号量对象,一个有界信号量会确保它当前的值不超过它的初始值。如果超过,则引发ValueError,在大部分情况下,信号量用于守护有限容量的资源。如果信号量被释放太多次,它是一种有bug的迹象,如果没有给出,value默认为1。

例如在下面的实例中,演示了使用BoundedSemaphore对象运行4个线程的过程。

import threading
import time


def fun(semaphore, num):
  # 获得信号量,信号量减一
  semaphore.acquire()
  print("thread %d is running." % num)
  time.sleep(3)
  # 释放信号量,信号量加一
  semaphore.release()
  # 再次释放信号量,信号量加一,这是超过限定的信号量数目,这时会报错VleE: Semaphore releaged too manytimes
  semaphore.release()


if __name__ == '__main__':
  # 初始化信号量,教量为2,最多有2个线程获得信号量,信号量不能通过释放而大于2
  semaphore = threading.BoundedSemaphore(2)
  # 运行4个线程
  for num in range(4):
    t = threading.Thread(target=fun, args=(semaphore, num))
    t.start()

文章来源:https://blog.csdn.net/weixin_47021806/article/details/115535520

标签:BoundedSemaphore,Semaphore,信号量,计数器,线程,semaphore,多线程
From: https://www.cnblogs.com/super-ma/p/17563363.html

相关文章

  • C#中可以通过管道流实现多线程之间数据交换
    //Console.WriteLine("=======创建线程=========");//ServerThreadserverThreadInstance=newServerThread(pipeName);//ThreadserverThread=newThread(newThreadStart(serverThreadInstance.run));//serverThread.Start();......
  • spring boot 接口多线程
    SpringBoot接口多线程在单线程的环境中,当接口请求过多时,容易造成阻塞和性能问题。为了提高系统的响应速度和吞吐量,我们可以使用多线程来处理接口请求。本文将介绍如何在SpringBoot中使用多线程处理接口请求,并给出相应的代码示例。什么是多线程多线程是指在一个进程中同时执行......
  • Java-多线程-八股文
    线程安全的理解?线程安全说的是,当多个线程并发访问互斥资源时,读写互斥资源的代码逻辑能正常处理,获得正确结果,不会互相干扰的情况。守护线程的理解?守护线程是与普通线程相区分的概念,用户一般使用的就是普通线程,普通线程有自身独立的生命周期,而守护线程的生命周期取决于普通......
  • Python的多线程(threading)与多进程(multiprocessing )
    可以用来做后台任务,可以在djangoview中调用,当做异步任务考核系统中要的threading,用来异步考核结果和考核进度的统计Python的多线程(threading)与多进程(multiprocessing)......
  • 进程、线程、多线程
    一、概念1进程的概念程序在服务器上运行时,占据的计算资源合集,称之为进程进程之间不会相互干扰---进程间的通信比较困难(分布式)进程是计算机操作系统中正在运行的程序的实例。通过任务管理器可以查看运行进程。前台进程:用户可以看见相应的操作界面,如:浏览器进程等后台进程......
  • shell多线程/实例
    1.Shell实现多进程  使用&和wait配合实现shell多进程并行  参考连接:https://blog.csdn.net/yuefei169/article/details/83340480  (1)改串行执行为并行执行方式:将前台执行命令放在后台执行(串行命令后加&符号).(生产少使用该方式)  (2)使用元祖模拟队列来控制进程数......
  • 工程开发 | CMake工程目录结构和多线程
    CMake工程目录结构lib:生成的库文件src:源文件(.cpp.cc)include:头文件(.h.hpp)build:一般在这个文件夹下执行cmake..(..之前有一个空格,表示你要使用的CMakeLists.txt文件在当前的上层路径),生成的Makefile文件也在这个路径下。bin:一般放生成的可执行文件CMakeLists.t......
  • 多线程基础
    1.继承Thread类重写run方法启动调用start方法缺点不能继承其他类优点简单2.定义任务类继承 Runnable接口实现 run方法   MyRunable为自定义的任务类 优点可以继承其他类 Runnablet=newMyRunable();newThread(t).start();3.JDK5.0提供了C......
  • SpringBoot中使用Netty开发WebSocket服务-netty-websocket-spring-boot-starter开源项
    场景SpringBoot+Vue整合WebSocket实现前后端消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114392573SpringCloud(若依微服务版为例)集成WebSocket实现前后端的消息推送:https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/114480731若依前后......
  • Java入门12(多线程)
    多线程线程的实现方式继承Thread类:一旦继承了Thread类,就不能再继承其他类了,可拓展性差实现Runnable接口:仍然可以继承其他类,可拓展性较好使用线程池继承Thread类​ 不能通过线程对象调用run()方法,需要通过t1.start()方法,使线程进入到就绪状态,只要进入到就绪状态......