多线程-同步对象 队列 生产者消费者模式

多线程

同步对象

解决什么问题?

想要指定的一个线程先执行,再去执行其他线程

精华如下

#event = threading.Event()
# event.isSet():返回event的状态值;
#
# event.wait():如果 event.isSet()==False将阻塞线程;
#
# event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
#
# event.clear():恢复event的状态值为False。
import threading
import time

ll=[]

class Boss(threading.Thread):
    def run(self):
        print("老板说今天23:00下班")
        print(event.is_set())
        time.sleep(1)
        event.set()
        time.sleep(6)
        print("老板说时间到了下班")
        event.set()

class Worker(threading.Thread):
    def run(self):
        event.wait()
        print("员工说:不要加班啊!!")
        event.clear()
        event.wait()
        print("员工说:下班下班!")

if __name__ == '__main__':
    event = threading.Event()
    boss=Boss()
    ll.append(boss)
    for i in range(5):
        i=Worker()
        ll.append(i)
    for z in ll:
        z.start()

信号量

相当于一次可以多个线程的同步锁

输出结果:一次打印5个线程的输出

import threading
import time

class zx(threading.Thread):
    def run(self):
        semaphore.acquire()
        time.sleep(3)
        print(self.name)
        semaphore.release()

if __name__ == '__main__':
    thr=[]
    semaphore=threading.Semaphore(5)
    for i in range(100):
        i=zx()
        i.start()

Thread-1
Thread-4
Thread-2
Thread-3
Thread-5
Thread-6
Thread-9
Thread-7
Thread-8
Thread-10

....

队列queue

list是线程不安全的

queue是线程安全的

可以让多个线程存取数据,不会出现问题

队列常用方法

Queue.task_done():队列计数器-1

Queue.join(): block直到queue被消费完毕

队列有三种存取方式

1.先进先出

import queue

q=queue.Queue()
q.put("sad")
q.put("123")
q.put("sady7854")

while 1:
    print(q.get())

sad
123
sady7854

2.先进后出

import queue

q=queue.LifoQueue()
q.put("sad")
q.put("123")
q.put("sady7854")

while 1:
    print(q.get())
sady7854
123
sad

3.按优先级

import queue

q=queue.PriorityQueue()
#注意这里用的是元组
q.put((3,"sad"))
q.put((1,"123"))
q.put((2,"sady7854"))

while 1:
    print(q.get())
(1, '123')
(2, 'sady7854')
(3, 'sad')

当数据插入,队列满了,他就会等待,取出一个在存入,默认不报错,可以设置报错

取数据时,当数据没有了,他会等待一个存入,再取出,默认也不报错

生产者消费者模型(队列)

生产者:生产数据的任务

消费者:处理数据的任务

举个例子:包子生产出来放在,货架上,有顾客来了,就买走。货架就相当于队列

代码实现了一个简单的例子,并不完善,用于理解

提高生产者生产的效率和消费者消费的效率

import queue
import threading
import random
import time

def producer(name):
    while 1:
        print(f"{name}正在制作包子")
        t=random.randint(1,4)
        time.sleep(t)
        bao_zi_que.put("包子")
        print("新出炉的包子哟!")
        bao_zi_que.task_done()#通知join有内容了,不用等待了
        time.sleep(0.5)

def customer(name):
    while 1:
        print(f"{name}在等待包子")
        bao_zi_que.join()
        bao_zi_que.get()
        time.sleep(1)
        print(f"{name}吃掉了包子")

bao_zi_que=queue.Queue()

if __name__ == '__main__':
    print("欢迎来到源氏百年包子店")
    A=threading.Thread(target=producer,args=("包子老板",))
    B=threading.Thread(target=customer,args=("zx",))
    C=threading.Thread(target=customer,args=("wl",))
    D=threading.Thread(target=customer,args=("125",))
    A.start()
    B.start()
    C.start()
    D.start()

欢迎来到源氏百年包子店
包子老板正在制作包子
zx在等待包子
wl在等待包子
125在等待包子
新出炉的包子哟!
包子老板正在制作包子
zx吃掉了包子
zx在等待包子
新出炉的包子哟!
包子老板正在制作包子
wl吃掉了包子
wl在等待包子
新出炉的包子哟!
包子老板正在制作包子
125吃掉了包子
125在等待包子
新出炉的包子哟!
包子老板正在制作包子
zx吃掉了包子
zx在等待包子
新出炉的包子哟!
包子老板正在制作包子
wl吃掉了包子
wl在等待包子
新出炉的包子哟!
包子老板正在制作包子

posted @ 2019-09-01 21:21  zx125  阅读(346)  评论(0编辑  收藏  举报