多线程-同步对象 队列 生产者消费者模式
多线程
同步对象
解决什么问题?
想要指定的一个线程先执行,再去执行其他线程
精华如下
#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在等待包子
新出炉的包子哟!
包子老板正在制作包子