一、多线程的事件
多线程的事件:说白了就是一个进程中的不同的线程之间可以相互影响,相互更改数据的过程。就比如说,一个线程是老师,另一个线程是学生,学生就要受到老师的影响。
我们说一下多线程中事件处理的原理:全局内定义了一个内置标志flag,如果flag值为 False,那么当程序执行 event.wait()方法时就会阻塞、卡住,如果flag值为True,那么用event.wait() 方法时便不再阻塞。
Event的方法
声明一个事件:event=threading.Event()
event.set(): 将标志设为True,并通知所有处于等待阻塞状态的线程恢复运行状态。
event.clear(): 将标志设为False。
event.wait(): 如果标志为True将立即返回,否则阻塞线程,等待其他线程调用event.set()。
event.isSet(): 获取内置标志状态,返回True或False。
下面我们利用一个事例来演示一下事件的用法:我们声明两个线程分别代表红绿灯和车,这样车就会受到红绿灯的影响,就是说两个线程之间可以相互影响。
(1)声明一个函数,模拟红绿灯,认为当事件的标志位为True时候是绿灯, False时候是红灯
def lighter():
count=0
event.set() #先设置为绿灯
while True:
if count >20 and count <30: #20s到30s之间改成红灯
event.clear() #清空标志位,变为False,阻塞
print('红灯')
elif count>30: #红灯亮10s
event.set() #变绿灯
count=0
else:
print('绿灯')
time.sleep(1)
count +=1
(2)在声明一个模拟车运行的函数
def car(name):
while True:
if event.is_set(): #标志位是否为True 就是是否为绿灯
print('%s正在行驶'%name)
time.sleep(1)
else:
print('%s正在等待'%name)
event.wait() #阻塞中 等待标志位变为True
print('绿灯亮了,开始行驶')
生成两个线程看看是否达到预期效果:
car1=threading.Thread(target=car,args=('car1',))
car1.start()
l=threading.Thread(target= lighter,)
l.start()
结果是:
达到了我们想要的结果。
二、多线程的队列
队列:就是一个有顺序的容器,用来存放数据。和列表的区别 :列表拿走了东西还在里面 , 队列拿走东西就少了一个。
队列有3种分类:
- 数据先进先出:queue.Queue()
- 数据后入先出:queue.LifoQueue()
- 数据可以设置优先级先出:queue.PriorityQueue()
下面我们举一个简单的例子来说明队列的用法:
import queue
q=queue.Queue() #先入先出 q=queue.Queue(maxsize=n) 最多只能存放n个
q.put('d1') #放数据
q.put('d2')
q.put('d3')
size=q.qsize() #队列里数据个数
print(size )
print(q.get()) #先入先出 取出d1
print(q.get()) #先入先出 取出d2
print(q.get()) #先入先出 取出d3
#q.get() #继续执行的话会一直等待 卡主 所以改成 q.get(block=False)或者q.get(timeout=1) 都会抛出异常
#q.get_nowait() #返回一个队列无数据异常
优先级的队列例子:
import queue
q=queue.PriorityQueue()
q.put((10,'dd'))
q.put((20,'aa'))
q.put((1,'bb'))
q.put((3,'cc'))
print(q.get()) # 取出1 bb
print(q.get()) # 取出3 cc
print(q.get()) # 取出 10 dd
print(q.get()) # 取出20 aa
这说一下队列的一个经典模型:生产者消费者模型
(1)写一个生产者函数,让他生产包子
def Producer(name):
count=0
while True:
q.put('包子%s'%count) #把生产的包子放入队列
print('生产了包子%s'%count )
count +=1
time.sleep(1)
(2)写一个消费者函数,购买包子
def Consumer(name):
while True:
print('%s买了%s,并且吃了它'%(name,q.get()))
time.sleep(1)
(2)生成一个生产者,两个消费者
p=threading.Thread(target= Producer,args= ('人物a',))
c =threading.Thread(target= Consumer,args= ('人物b',))
c1=threading.Thread(target= Consumer,args= ('人物c',))
p.start()
c.start()
c1.start()
看一下结果:
这就是经典的生产者消费者 队列模型,把生产的物品放入队列,消费者自动购买。