Python的线程使用队列Queue来改造转账场景

 更新时间:2022年02月24日 11:27:56   作者:雷学委  
前篇我们了队列Queue和转账场景这次趁热学委展示一下使用队列解决转账场景的问题,这篇文章主要介绍了Python的线程使用队列来改造转账场景,需要的朋友可以参考一下

前篇我们了队列Queue转账场景这次趁热学委展示一下使用队列解决转账场景的问题。

一、看看转账场景的问题

前面有两篇文章展示了转账反复读写amount,导致结果出错。

xuewei_account = dict()
xuewei_account['amount'] = 100

# amount为负数即是转出金额
def transfer(money):
    for i in range(100000):
        xuewei_account['amount'] = xuewei_account['amount'] + money

我们前几篇使用多个线程反复转长:+1和-1。

按常理,结果应该仍旧是100.

这个是全部代码:

import random
import threading
import datetime
import time

xuewei_account = dict()
xuewei_account['amount'] = 100


# amount为负数即是转出金额
def transfer(money):
    for i in range(100000):
        xuewei_account['amount'] = xuewei_account['amount'] + money


# 创建20个任务重复给学委账户转账
threads = []
for i in range(10):
    t1 = threading.Thread(target=lambda: transfer(-1))
    threads.append(t1)
    t2 = threading.Thread(target=lambda: transfer(1))
    threads.append(t2)

for t in threads:
    t.start()
for t in threads:
    t.join()

print("-" * 16)
print("活跃线程数:", threading.active_count())
print("活跃线程:", threading.current_thread().name)
print("学委账户余额:", xuewei_account)

等待所有转账线程运行结束,我们看到结果是错误的:

二、这种问题怎么使用队列来解决呢?

前面说了,多线程反复读写共享数据,是问题的根源。

改代码为同步互斥模式,保证任意一个时间一个线程更新共享数据,那么问题就解决了。(这前面也展示了,用的是Lock锁的方案)

这个能怎么用队列呢?

可以先思考10秒,根据学习到的加锁和队列的特性,想想这个怎么做。

好,答案现在揭晓:

Queue这个队列有多个函数,一个是put函数,一个是get函数。

一个负责放入数据到队尾,一个可以从对头取出元素。

刚好适合转账业务,我们是不是可以把每次转账操作变成一个一个指令/事件。 比如下面的:

event(amount=1,acount=xuewei_account)
....
event(amount=-1,acount=xuewei_account)
....
event(amount=1,acount=xuewei_account)
....
event(amount=-1,acount=xuewei_account)

20个线程,每个10万次数据读写,共200万个事件。

所以我们可以把这个事情转换为:200万个转账事件。

因为Queue是线程安全的,所以我们可以并发200万次转账,另外交给一线程进行转账处理。

这样就保证每次只有一个线程对xuewei_account学委账户进行读写。

改造,使用队列来解决问题

展示代码:

import random
import threading
import datetime
import time
import queue

q = queue.Queue()

xuewei_account = dict()
xuewei_account['amount'] = 100


# amount为负数即是转出金额
def transfer(money):
    for i in range(100000):
        q.put(money)


def handle_amount():
    while not q.empty():
        amount = q.get()
        xuewei_account['amount'] += amount


def monitor_q():
    counter = 0
    time.sleep(3)
    while counter < 1000 and not q.empty():
        print("q size:", q.qsize())
        time.sleep(3)
        counter+=1


q_thread = threading.Thread(name="Q监控", target=monitor_q)
q_thread.start()
# 创建20个任务重复给学委账户转账
threads = []
for i in range(10):
    t1 = threading.Thread(target=lambda: transfer(-1))
    threads.append(t1)
    t2 = threading.Thread(target=lambda: transfer(1))
    threads.append(t2)

for t in threads:
    t.start()

vip_thread = threading.Thread(name="处理转账专线", target=handle_amount)
vip_thread.start()

for t in threads:
    t.join()
vip_thread.join()

print("-" * 16)
print("活跃线程数:", threading.active_count())
print("活跃线程:", threading.current_thread().name)
print("学委账户余额:", xuewei_account)

这里运行了多个线程执行转账(发送转账金额进队列)。

然后运行一个vip通道(单独线程)处理学委账户的转账业务。

同时也运行了一个监控队列的线程,每隔一段时间打印队列的任务情况。

下面是运行结果,运行几次结果都是正确的。

运行几次最终账户余额都是100, 改造成功。

三、总结

本篇学委分享了线程安全的队列Queue解决并发转账问题。

其实代码还可以再度优化的,为了控制篇幅,代码也不少,希望读者朋友们能够先看熟学会,掌握队列的使用。

到此这篇关于Python的线程使用队列来改造转账场景的文章就介绍到这了,更多相关Python使用队列来改造转账场景内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • python内置函数:lambda、map、filter简单介绍

    python内置函数:lambda、map、filter简单介绍

    Python 内置了一些比较特殊且实用的函数,使用这些能使你的代码简洁而易读。下面对python内置函数:lambda、map、filter简单介绍下,需要的朋友参考下吧
    2017-11-11
  • Python+Pygame实现之走四棋儿游戏的实现

    Python+Pygame实现之走四棋儿游戏的实现

    大家以前应该都听说过一个游戏:叫做走四棋儿。直接在家里的水泥地上用烧完的炭火灰画出几条线,摆上几颗石头子即可。当时的火爆程度可谓是达到了一个新的高度。本文将利用Pygame实现这一游戏,需要的可以参考一下
    2022-07-07
  • 将python图片转为二进制文本的实例

    将python图片转为二进制文本的实例

    今天小编就为大家分享一篇将python图片转为二进制文本的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01
  • Selenium常见八大定位法总结

    Selenium常见八大定位法总结

    自动化最基础的就属于定位元素了,元素不会定位,基本上已经团灭了,就不用再去考虑什么自动化了,下面这篇文章主要给大家介绍了关于Selenium常见八大定位法的相关资料,需要的朋友可以参考下
    2023-02-02
  • Python爬虫入门教程01之爬取豆瓣Top电影

    Python爬虫入门教程01之爬取豆瓣Top电影

    这篇文章主要介绍了Python爬虫入门教程01:豆瓣Top电影爬取的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • python实现字符串完美拆分split()的方法

    python实现字符串完美拆分split()的方法

    今天小编就为大家分享一篇python实现字符串完美拆分split()的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-07-07
  • python实现3D地图可视化

    python实现3D地图可视化

    这篇文章主要为大家详细介绍了python实现3D地图可视化,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-03-03
  • 解决pycharm运行程序出现卡住scanning files to index索引的问题

    解决pycharm运行程序出现卡住scanning files to index索引的问题

    今天小编就为大家分享一篇解决pycharm运行程序出现卡住scanning files to index索引的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • Python实现多级目录压缩与解压文件的方法

    Python实现多级目录压缩与解压文件的方法

    这篇文章主要介绍了Python实现多级目录压缩与解压文件的方法,涉及Python针对文件路径的遍历、判断以及文件压缩、解压缩等相关操作技巧,需要的朋友可以参考下
    2018-09-09
  • python读取excel数据并且画图的实现示例

    python读取excel数据并且画图的实现示例

    这篇文章主要介绍了python读取excel数据并且画图的实现示例,帮助大家更好的理解和使用python,感兴趣的朋友可以了解下
    2021-02-02

最新评论