Python的线程07 带你验收一款线程安全的队列
Posted 雷学委
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python的线程07 带你验收一款线程安全的队列相关的知识,希望对你有一定的参考价值。
正式的Python专栏第45篇,同学站住,别错过这个从0开始的文章!
前面多篇文章详细讲解了线程和线程安全,以及一些程序多线程错误下的,线程安全改造。
是否有一种神器,解决线程/并发的问题呢?
有,它就是队列(Queue)
什么是队列?
像排队一样,从头到尾排成一排,还可以有人继续往后排队,这就是队列。
这里学委想说的是Queue这个类, 它是queue这个内置模块内的一个类。
import queue
q = queue.Queue(5) #可以传入参数指定队列大小
queue.Queue()# 不传或者给0或者<0的数字则创建一个无限长度的队列
它提供了很多函数,下面几个函数,我们使用的比较多:
- get: 获取并移除队头元素,就是出队
- put: 往队列末尾加入元素,也就是后来者排队
- qsize: 获取队列的长度
- empty: 队列空了,没有人在排了
- full: 队列满了。
看着比较枯燥,学委画了下图展示:
这个队列put了3次,依次放入:持续学习,持续开发,我雷学委。队列长度为3
队列基操 入队/出队/查队列状态
学委准备了下面的代码:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/24 12:02 上午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : threadsafe_queue0.py
# @Project : hello
import queue
q = queue.Queue(5)
print("学委粉丝队列:", q)
print("空队,学委粉丝队列大小:", q.qsize())
print("空队列?", q.empty())
for i in range(5):
q.put(i)
print("队列满了?", q.full())
print("排满了,学委粉丝队列大小:", q.qsize())
while not q.empty():
print("粉丝 %s 出队点赞!" % q.get())
print("最后,学委粉丝队列大小:", q.qsize())
这段代码创建了一个长的为5的队列。
然后一个循环写满队列,接着再依此出队,粉丝出队点赞。
下面是运行效果:
是不是很简单。
好消息,Queue这个是一个线程安全的类
前面学委展示了几篇文章,碰到下面的代码(反复读写共享变量)结果总是出乎依赖!
amount = 100
def transfer(money):
global amount
for i in range(100000):
amount += money
如果我们对队列进行反复读写,会不会出现问题呢?
不妨,写个代码验收一下:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2021/11/24 12:02 上午
# @Author : LeiXueWei
# @CSDN/Juejin/Wechat: 雷学委
# @XueWeiTag: CodingDemo
# @File : threadsafe_queue1.py
# @Project : hello
import queue
import threading
xuewei_fans_q = queue.Queue()
def transfer(money):
for i in range(100000):
xuewei_fans_q.put(money)
xuewei_fans_q.get()
# 创建4个任务重复给学委加关注/脱粉(还是希望各位编程的明日之星跟着学习,共同进步!)
t_group = []
for i in range(10):
t = threading.Thread(target=lambda: transfer(-1))
t_group.append(t)
t.start()
t = threading.Thread(target=lambda: transfer(1))
t_group.append(t)
t.start()
t = threading.Thread(target=lambda: transfer(-1))
t_group.append(t)
t.start()
t = threading.Thread(target=lambda: transfer(1))
t_group.append(t)
t.start()
for t in t_group:
t.join()
print("-" * 16)
print("活跃线程数:", threading.active_count())
print("活跃线程:", threading.current_thread().name)
#反复对队列进行添加数据,移除数据,队列最后清零了
print("学委粉丝队列:", xuewei_fans_q.qsize())
不管运行多少次,队列(希望是黑粉队列)都为0元素。
总结
本篇学委分享了一个线程安全的队列Queue,这个非常重要!
前面花了很多篇幅讲解多线程出现的一些问题和解决,很麻烦。
但是队列Queue这个类是线程安全的,这个是经过验证的,读者朋友务必掌握牢固。
虽然展示的队列是粉丝队列,学委还是希望各位编程的明日之星跟着学习,一起共同进步!
下一篇学委将分享用队列改造转账程序,优雅的解决转账金额错误的问题。
对了,喜欢Python的朋友,请关注学委的 Python基础专栏 or Python入门到精通大专栏
持续学习持续开发,我是雷学委!
编程很有趣,关键是把技术搞透彻讲明白。
欢迎关注微信,点赞支持收藏!
以上是关于Python的线程07 带你验收一款线程安全的队列的主要内容,如果未能解决你的问题,请参考以下文章