python系列——多线程之Semaphore信号量及

tech2022-09-15  69

参考博客:

https://segmentfault.com/a/1190000008123688  (以图的方式解释了lock锁、rlock锁、semaphore信号量)

http://blog.sina.com.cn/s/blog_82fefc100102xg97.html  (以semaphore信号量实现了生产者消费者)

https://blog.csdn.net/qq_33371343/article/details/79201161  (解释了semaphore信号量中信号量的功能)

https://www.jianshu.com/p/e52154188acc  (以实际semaphore的代码展示了如何允许指定数量的线程同时运行)

http://www.manongjc.com/detail/15-tdstifzseqcxlaw.html  (介绍了semaphore信号量和BoundedSemaphore有界信号量的区别)

初始印象:

简单点说,Semphore,是一种带计数的线程同步机制,当调用release时,增加计数,当acquire时,减少计数,当计数为0时,自动阻塞,等待release被调用。

什么时候被使用:

import time import threading def foo(): time.sleep(2) #程序休息2秒 print("ok",time.ctime()) for i in range(20): t1=threading.Thread(target=foo,args=()) #实例化一个线程 t1.start() #启动线程 输出: ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017 ok Tue Jul 18 20:05:58 2017

可以看到,程序会在很短的时间内生成20个线程来打印一句话,如果在主机执行IO密集型任务的时候再执行这种类型的程序时,计算机就有很大可能会宕机。 这时候就可以为这段程序添加一个计数器功能,来限制一个时间点内的线程数量。

使用方法:指定数量的线程同时运行:

# -*- coding:utf-8 -*- import threading import time sem = threading.Semaphore(3) class DemoThread(threading.Thread): def run(self): print('{0} is waiting semaphore.'.format(self.name)) sem.acquire() print('{0} acquired semaphore({1}).'.format(self.name, time.ctime())) time.sleep(5) print('{0} release semaphore.'.format(self.name)) sem.release() if __name__ == '__main__': threads = [] for i in range(4): threads.append(DemoThread(name='Thread-' + str(i))) for t in threads: t.start() for t in threads: t.join()

结果:

Thread-0 is waiting semaphore. Thread-0 acquired semaphore(Thu Oct 25 20:33:18 2018). Thread-1 is waiting semaphore. Thread-1 acquired semaphore(Thu Oct 25 20:33:18 2018). Thread-2 is waiting semaphore. Thread-2 acquired semaphore(Thu Oct 25 20:33:18 2018). Thread-3 is waiting semaphore. Thread-0 release semaphore. Thread-3 acquired semaphore(Thu Oct 25 20:33:23 2018). Thread-1 release semaphore. Thread-2 release semaphore. Thread-3 release semaphore.

有界信号量boundageSamephore:

BoundedSemaphore在调用release()的时候,会校验一下当前信号量的值,是否会大于初始值(只定义了5个信号量,释放了5次后,还要调用release)的场景,会抛出异常,而 Semaphore在这种场景下,release()的结果只是None,没有返回信号量对象,并不会抛出异常。

具体例子:

import threading #sem=threading.BoundedSemaphore(5) sem=threading.Semaphore(5) global num num=0 def run(): global num sem.acquire() num+=1 if num>0: sem.release() print(sem.release()) for i in range(20): threading.Thread(target=run,args=()).start() print(num)

 

最新回复(0)