python多线程(二)

一、多线程的事件

多线程的事件:说白了就是一个进程中的不同的线程之间可以相互影响,相互更改数据的过程。就比如说,一个线程是老师,另一个线程是学生,学生就要受到老师的影响。
我们说一下多线程中事件处理的原理:全局内定义了一个内置标志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种分类:

  1. 数据先进先出:queue.Queue()
  2. 数据后入先出:queue.LifoQueue()
  3. 数据可以设置优先级先出: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()

看一下结果:
这里写图片描述
这就是经典的生产者消费者 队列模型,把生产的物品放入队列,消费者自动购买。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值