文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Python线程怎么解决共享变量问题

2023-06-29 07:09

关注

这篇文章主要介绍“Python线程怎么解决共享变量问题”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Python线程怎么解决共享变量问题”文章能帮助大家解决问题。

下面展示另一种转账的方式:

import randomimport threadingimport datetimeimport timexuewei = {'balance': 157}# amount为负数即是转出金额def transfer(money):    name = threading.current_thread().getName()    print("%s 给xuewei转账 %s " % (name, money))    xuewei['balance'] += money    print("xuewei账户余额:", xuewei['balance'])lists = [-7, 20, -20, 7]  # 4次转账的数额,负数为学委的账户转出,正数为他人转入。# 创建4个任务给学委转账上面lists的金额threads = []for i in range(4):    amount = lists[i]    name = "t-" + str(i)    print("%s 计划转账 %s" % (name, amount))    mythread = threading.Thread(name=name, target=lambda: transfer(amount))    threads.append(mythread)# 开始转账for t in threads:    t.start()# 等待3秒让上面的转账任务都完成,我们在看看账户余额time.sleep(3)print("-" * 16)print("学委账户余额:", xuewei['balance'])

这里启动了4个线程,每个线程内有个lambda表达式,分别于学委的账户进行转账,但是最后结果是185. 而不是157.

下面是运行结果:

Python线程怎么解决共享变量问题

PS: 这只是一种运行结果。多线程的运行结果不是永远一样的。

如何解决这个问题?

观测结果我们发先amount只保留了最后一个值。

好,下面改造一下:

import randomimport threadingimport datetimeimport timexuewei = {'balance': 157}lists = [-7, 20, -20, 7]  # 4次转账的数额,负数为学委的账户转出,正数为他人转入。def transfer(amount):    name = threading.current_thread().getName()    print("%s 给xuewei转账 %s " % (name,amount))    xuewei['balance'] += amount    print("xuewei账户余额:", xuewei['balance'])# 创建4个任务给学委转账上面lists的金额for i in range(4):    amount = lists[i]    name = str(i)    # mythread = threading.Thread(name=name, target=lambda: transfer(amount))    def event():        print("%s 计划转账 %s" % (name, amount))        transfer(amount)    mythread = threading.Thread(name=name, target=event)    mythread.start()# 等待3秒让上面的转账任务都完成,我们在看看账户余额time.sleep(3)print("-" * 16)print("学委账户余额:", xuewei['balance'])

学委这里加了一个event函数,把转账计划打印出来。

从下面的一次运行结果看,event函数的输出结果没错,所有”计划转账“金额都如预期[-7, 20, -20 7]。 问题是transfer函数再多线程执行的时候,我们发现amount被多线程竞争修改了:

用户0转账金额变成20
用户1转账金额变成-20
用户2转账金额变成7
用户3转账金额变成7

Python线程怎么解决共享变量问题

也就是说,amount被后面的线程修改了,但是前面线程还没有执行完。
用户0应该转账-7的,中间还没有执行完毕,结果被线程1修改了amount为20,用户0继续执行转账,余额变成177. 其他依次推理。

amount这个变量被多个线程竞争修改了,这个就是程序的共享变量。

到底如何解决?

方法非常简单:直接干掉共享变量。

下面就是消除共享变量的方法: 让共享变成每个线程访问独立运行空间

所以代码改动如下:

import randomimport threadingimport datetimeimport timexuewei = {'balance': 157}lists = [-7, 20, -20, 7]  # 4次转账的数额,负数为学委的账户转出,正数为他人转入。# 我们不要依赖amount变量了def transfer():    name = threading.current_thread().getName()    xuewei['balance'] += lists[int(name)] #通过线程名字来获取对应金额    print("xuewei账户余额:", xuewei['balance'])# 创建4个任务给学委转账上面lists的金额threads = []for i in range(4):    amount = lists[i]    name = str(i)    print("%s 计划转账 %s" % (name, amount))    # mythread = threading.Thread(name=name, target=lambda: transfer())    def event():        transfer()    mythread = threading.Thread(name=name, target=event)    threads.append(mythread)# 开始转账for t in threads:    t.start()# 等待3秒让上面的转账任务都完成,我们在看看账户余额time.sleep(3)print("-" * 16)print("学委账户余额:", xuewei['balance'])

运行结果如下:

Python线程怎么解决共享变量问题

上面的代码不管怎么运行,运行多少次最后学委的账户都是157.

这次展示的另一种方式来避开多线程出现bug的方法,使用一个list下标跟线程名字一一对应,这样只要是对应名字的线程拿到的数值不错错乱。

关于“Python线程怎么解决共享变量问题”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯