首页 技术 正文
技术 2022年11月17日
0 收藏 787 点赞 3,403 浏览 2915 个字

Semaphore 信号量对象

信号量是一个更高级的锁机制。信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞。这允许了多个线程可以同时访问相同的代码区。

Semaphore管理一个内置的计数器,每当调用acquire()时内置计数器-1;调用release() 时内置计数器+1;

计数器不能小于0;当计数器为0时,acquire()将阻塞线程直到其他线程调用release()。

直接上代码,我们把semaphore控制为3,也就是说,同时有3个线程可以用这个锁,剩下的线程也之只能是阻塞等待。

# coding:utf-8import time
import threadingsemaphore = threading.Semaphore(3)def func():
if semaphore.acquire():
print (threading.currentThread().getName() + '获取锁')
time.sleep(5)
semaphore.release()
print (threading.currentThread().getName() + '释放锁')for i in range(10):
t1 = threading.Thread(target=func)
t1.start()
Thread-1获取锁
Thread-2获取锁
Thread-3获取锁
Thread-3释放锁
Thread-2释放锁
Thread-4获取锁
Thread-5获取锁
Thread-1释放锁
Thread-6获取锁
Thread-6释放锁
Thread-7获取锁
Thread-4释放锁
Thread-8获取锁
Thread-5释放锁
Thread-9获取锁
Thread-8释放锁
Thread-10获取锁
Thread-7释放锁
Thread-9释放锁
Thread-10释放锁

Event事件

Event内部包含了一个标志位,初始的时候为false。

可以使用使用set()来将其设置为true;

或者使用clear()将其从新设置为false;

可以使用is_set()来检查标志位的状态;

另一个最重要的函数就是wait(timeout=None),用来阻塞当前线程,直到event的内部标志位被设置为true或者timeout超时。如果内部标志位为true则wait()函数理解返回。

# coding:utf-8import threading
import time
event = threading.Event()def service():
print('开启服务')
event.wait() # 括号里可以带数字执行,数字表示等待的秒数,不带数字表示一直阻塞状态
print('服务开启成功')def start():
time.sleep(3)
print('开始执行业务')
time.sleep(3)
event.set() # 默认为False,set一次表示True,所以子线程里的foo函数解除阻塞状态继续执行def conn():
while True:
if event.is_set() == False:
print('数据库连接成功')
time.sleep(1)
event.set()
event.wait()
breakt = threading.Thread(target=service, args=()) # 子线程执行foo函数
t.start()
t2 = threading.Thread(target=start, args=()) # 子线程执行start函数
t2.start()
t3 = threading.Thread(target=conn, args=()) # 子线程执行do函数
t3.start()
开启服务
数据库连接成功
服务开启成功
开始执行业务

Condition

可以把Condition理解为一把高级的琐,它提供了比Lock, RLock更高级的功能,允许我们能够控制复杂的线程同步问题。threadiong.Condition在内部维护一个琐对象(默认是RLock),可以在创建Condigtion对象的时候把琐对象作为参数传入。Condition也提供了acquire, release方法,其含义与琐的acquire, release方法一致,其实它只是简单的调用内部琐对象的对应的方法而已。Condition还提供了如下方法(特别要注意:这些方法只有在占用琐(acquire)之后才能调用,否则将会报RuntimeError异常。):

Condition.wait([timeout]):

wait方法释放内部所占用的琐,同时线程被挂起,直至接收到通知被唤醒或超时(如果提供了timeout参数的话)。当线程被唤醒并重新占有琐的时候,程序才会继续执行下去。

Condition.notify():

唤醒一个挂起的线程(如果存在挂起的线程)。注意:notify()方法不会释放所占用的琐。

Condition.notify_all()

Condition.notifyAll()

唤醒所有挂起的线程(如果存在挂起的线程)。注意:这些方法不会释放所占用的琐。

以下为生产者消费者模式示例:

# coding:utf-8from threading import Thread, Condition
import time
import randomqueue = []
MAX_NUM = 10
condition = Condition()class ProducerThread(Thread): def run(self):
nums = range(5)
global queue
while True:
condition.acquire()
if len(queue) == MAX_NUM:
print ("Queue full, producer is waiting")
condition.wait()
print ("Space in queue, Consumer notified the producer")
num = random.choice(nums)
queue.append(num)
print ("Produced", num)
condition.notify()
condition.release()
time.sleep(random.random())class ConsumerThread(Thread): def run(self):
global queue
while True:
condition.acquire()
if not queue:
print ("Nothing in queue, consumer is waiting")
condition.wait()
print ("Producer added something to queue and notified the consumer")
num = queue.pop(0)
print ("Consumed", num)
condition.notify()
condition.release()
time.sleep(random.random())ProducerThread().start()
ConsumerThread().start()
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,104
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,581
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,428
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,200
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,835
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,918