Python 多线程共享变量的实现示例


Posted in Python onApril 17, 2020

多线程-共享全局变量

#coding=utf-8
from threading import Thread
import time

g_num = 100

def work1():
 global g_num
 for i in range(3):
  g_num += 1

 print("----in work1, g_num is %d---"%g_num)


def work2():
 global g_num
 print("----in work2, g_num is %d---"%g_num)


print("---线程创建之前g_num is %d---"%g_num)

t1 = Thread(target=work1)
t1.start()

#延时一会,保证t1线程中的事情做完
time.sleep(1)

t2 = Thread(target=work2)
t2.start()

执行如下:

[root@server01 many_task]# python test5.py
---线程创建之前g_num is 100---
----in work1, g_num is 103---
----in work2, g_num is 103---
[root@server01 many_task]#

从上面两个线程执行的结果来看,线程t1将 g_num 加到 103,在线程t2也是打印g_num=103。所以对于两个线程,g_num这个全局变量是共享的。

列表当做实参传递到线程中

#coding=utf-8
from threading import Thread
import time

def work1(nums):
 nums.append(44)
 print("----in work1---",nums)

def work2(nums):
 #延时一会,保证t1线程中的事情做完
 time.sleep(1)
 print("----in work2---",nums)

g_nums = [11,22,33]

t1 = Thread(target=work1, args=(g_nums,))
t1.start()

t2 = Thread(target=work2, args=(g_nums,))
t2.start()

运行如下:

[root@server01 many_task]# python test6.py
('----in work1---', [11, 22, 33, 44])
('----in work2---', [11, 22, 33, 44])

总结:
在一个进程内的所有线程共享全局变量,很方便在多个线程间共享数据
缺点就是,线程是对全局变量随意遂改可能造成多线程之间对全局变量的混乱(即线程非安全)

多线程-共享全局变量问题

多线程开发可能遇到的问题

假设两个线程t1和t2都要对全局变量g_num(默认是0)进行加1运算,t1和t2都各对g_num加10次,g_num的最终的结果应该为20。

但是由于是多线程同时操作,有可能出现下面情况:

在g_num=0时,t1取得g_num=0。此时系统把t1调度为”sleeping”状态,把t2转换为”running”状态,t2也获得g_num=0
然后t2对得到的值进行加1并赋给g_num,使得g_num=1
然后系统又把t2调度为”sleeping”,把t1转为”running”。线程t1又把它之前得到的0加1后赋值给g_num。
这样导致虽然t1和t2都对g_num加1,但结果仍然是g_num=1

编写代码测试如下:

[root@server01 many_task]# vim test4.py 

#coding=utf-8
import threading
from time import sleep,ctime

# 初始化g_num
g_num = 0

def add_func1(num):
 global g_num
 for i in range(num):
  g_num += 1
  print("add_func1,第%d次,g_num等于%d" % (i,g_num))
  #sleep(0.5)

def add_func2(num):
 global g_num
 for i in range(num):
  g_num += 1
  print("add_func2,第%d次,g_num等于%d" % (i,g_num))
  #sleep(0.5)

def main():
 # 执行线程
 t1 = threading.Thread(target=add_func1,args=(100,))
 t2 = threading.Thread(target=add_func2,args=(100,))

 t1.start()
 t2.start()

 # 判断当线程存在,则等待1秒
 while len(threading.enumerate()) > 1:
  sleep(1)

 print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)

if __name__ == '__main__':
 main()

执行如下:

add_func2,第96次,g_num等于197
add_func2,第97次,g_num等于198
add_func2,第98次,g_num等于199
add_func2,第99次,g_num等于200
2个线程对同一个全局变量操作之后的最终结果是:200
[root@server01 many_task]#

两个线程虽然执行很快,但是g_num恰好就是100+100=200的结果,是正确的。不过,这个数量少,可能看不出问题来。

测试示例2

[root@server01 many_task]# vim test7.py 

def work1(num):
 global g_num
 for i in range(num):
  g_num += 1
 print("----in work1, g_num is %d---"%g_num)


def work2(num):
 global g_num
 for i in range(num):
  g_num += 1
 print("----in work2, g_num is %d---"%g_num)


print("---线程创建之前g_num is %d---"%g_num)

t1 = threading.Thread(target=work1, args=(10000000,))
t1.start()

t2 = threading.Thread(target=work2, args=(10000000,))
t2.start()

while len(threading.enumerate()) != 1:
 time.sleep(1)

print("2个线程对同一个全局变量操作之后的最终结果是:%s" % g_num)

运行如下:

[root@server01 many_task]# python test7.py
---线程创建之前g_num is 0---
----in work1, g_num is 11977799---
----in work2, g_num is 19108796---
2个线程对同一个全局变量操作之后的最终结果是:19108796
[root@server01 many_task]#

正确的结果应该是:20000000

结论

如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确

到此这篇关于Python 多线程共享变量的实现示例的文章就介绍到这了,更多相关Python 多线程共享变量内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Linux下调试Python代码的各种方法
Apr 17 Python
Python编写生成验证码的脚本的教程
May 04 Python
Python函数式编程指南(一):函数式编程概述
Jun 24 Python
Python通过matplotlib绘制动画简单实例
Dec 13 Python
python实现自动网页截图并裁剪图片
Jul 30 Python
python调用摄像头显示图像的实例
Aug 03 Python
python使用xlrd和xlwt读写Excel文件的实例代码
Sep 05 Python
python如何给字典的键对应的值为字典项的字典赋值
Jul 05 Python
Django ImageFiled上传照片并显示的方法
Jul 28 Python
Python自动化导出zabbix数据并发邮件脚本
Aug 16 Python
Python嵌套函数,作用域与偏函数用法实例分析
Dec 26 Python
Python3+RIDE+RobotFramework自动化测试框架搭建过程详解
Sep 23 Python
matplotlib 对坐标的控制,加图例注释的操作
Apr 17 #Python
matplotlib quiver箭图绘制案例
Apr 17 #Python
更新升级python和pip版本后不生效的问题解决
Apr 17 #Python
浅谈python多线程和多线程变量共享问题介绍
Apr 17 #Python
使用Matplotlib绘制不同颜色的带箭头的线实例
Apr 17 #Python
matplotlib 曲线图 和 折线图 plt.plot()实例
Apr 17 #Python
Python实现自动打开电脑应用的示例代码
Apr 17 #Python
You might like
PHP+jQuery+Ajax实现分页效果 jPaginate插件的应用
2015/10/09 PHP
Yii框架实现图片上传的方法详解
2017/05/20 PHP
基于PHP实现用户在线状态检测
2020/11/10 PHP
ie和firefox中img对象区别的困惑
2006/12/27 Javascript
js模拟类继承小例子
2010/07/17 Javascript
setInterval,setTimeout与jquery混用的问题
2013/04/08 Javascript
jQuery获取样式中颜色值的方法
2015/01/29 Javascript
Jquery中的$.each获取各种返回类型数据的使用方法
2015/05/03 Javascript
基于Jquery实现万圣节快乐特效
2015/11/01 Javascript
angularjs自定义ng-model标签的属性
2016/01/21 Javascript
基于javascript显示当前时间以及倒计时功能
2016/03/18 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
vue2.0结合Element实现select动态控制input禁用实例
2017/05/12 Javascript
JScript实现表格的简单操作
2017/08/15 Javascript
微信小程序实现人脸检测功能
2018/05/25 Javascript
Vue学习笔记之计算属性与侦听器用法
2019/12/07 Javascript
NodeJS多种创建WebSocket监听的方式(三种)
2020/06/04 NodeJs
微信小程序实现页面左右滑动
2020/11/16 Javascript
python定时器(Timer)用法简单实例
2015/06/04 Python
浅谈python字符串方法的简单使用
2016/07/18 Python
Python列表(List)知识点总结
2019/02/18 Python
Pycharm插件(Grep Console)自定义规则输出颜色日志的方法
2020/05/27 Python
Django Session和Cookie分别实现记住用户登录状态操作
2020/07/02 Python
Python实现钉钉/企业微信自动打卡的示例代码
2021/02/02 Python
新加坡网上美容店:Hermo新加坡
2019/06/19 全球购物
长曲棍球装备:Lacrosse Monkey
2020/12/02 全球购物
精选干货:Java精选笔试题附答案
2014/01/18 面试题
工程造价与财务管理专业应届生求职信
2013/10/06 职场文书
成人毕业生自我鉴定
2013/10/18 职场文书
教师岗位职责
2013/11/17 职场文书
酒店总经理岗位职责
2014/03/17 职场文书
社区居务公开实施方案
2014/03/27 职场文书
大学专科自荐信
2014/06/17 职场文书
教师业务学习材料
2014/12/16 职场文书
2016学校元旦晚会经典开场白台词
2015/12/03 职场文书
解决Tkinter中button按钮未按却主动执行command函数的问题
2021/05/23 Python