内容包含:信息量,条件变量,事件。
回答问题:
(1)什么是信息量,条件变量,事件。
信息量:信号量通过其内部的一个int变量来控制行为,P和V操作时原子的。默认情况下,threading.Semaphore创建的信号量,内部int的初始值为1,此时行为模式与一个lock互斥量没啥区别。不过,有一个细节,信号量的release(即V操作)会增加其内部的int值,而且可以多次release。
在操作系统笔记中也可以体现信息量的定义:
信息量作用:控制可得到cpu的线程的个数。
在python中的使用:
条件变量:Python提供的Condition对象提供了对复杂线程同步问题的支持。Condition被称为条件变量,除了提供与Lock类似的acquire和release方法外,还提供了wait和notify方法。线程首先acquire一个条件变量,然后判断一些条件。如果条件不满足则wait;如果条件满足,进行一些处理改变条件后,通过notify方法通知其他线程,其他处于wait状态的线程接到通知后会重新判断条件。不断的重复这一过程,从而解决复杂的同步问题。
在操作系统笔记中也可以体现互斥锁对应的就是条件变量吧
在python中的使用:
事件:
事件处理的机制:全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么event.wait 方法时便不再阻塞。
Event其实就是一个简化版的 Condition。Event没有锁,无法使线程进入同步阻塞状态。
Event()
-
set(): 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态。
-
clear(): 将标志设为False。
-
wait(timeout): 如果标志为True将立即返回,否则阻塞线程至等待阻塞状态,等待其他线程调用set()。
-
isSet(): 获取内置标志状态,返回True或False。
-
(2)按步骤解释信号量,条件变量,事件
针对这一问题,我们直接在代码上进行演示
import threading
import time
def run(num):
semapshore.acquire() # 获得信号量(获取后就上锁了)
print(f'第{num}个人正在吃饭')
time.sleep(2)
semapshore.release() # 释放信号量(等于解锁)
if __name__ == '__main__':
# 一次只允许5人同时吃饭
semapshore = threading.Semaphore(5)
# 创建子线程
thread = [] #创建一个空的列表
for i in range(100):
t = threading.Thread(target=run, args=(i,))
t.start()
thread.append(t) #将创建的线程一个个放入刚刚创建好的空列表里
for t in thread:
t.join() #等待线程完成
#用for循环 就是等待所有线程都完成
import threading
import time
def Maths():
while 1: # 为了体现多线程所以一直循环(如何不加运行一次后该线程就结束了)
if event.is_set(): # 判断事件启动了没有,如果启动了就开始运行if语句
print("数学考试结束")
event.clear()
print("---------------------------------") # 分割线更好看清运行
else:
print("数学考试还在继续") # 事件没有启动则继续
event.wait()
def setEvent():
while 1:
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) # 输出时间
time.sleep(3) # 间隔3秒
event.set() # 启动事件
if __name__ == '__main__':
event = threading.Event() # 创建事件
set_event = threading.Thread(target=setEvent) # 建立线程
set_event.start() # 线程启动
math = threading.Thread(target=Maths) # 建立线程
math.start() # 线程启动