多线程-共享全局变量
#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
结论
如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新日志
- 完美倒立.2024-夜色碳酸【草台回声】【FLAC分轨】
- 杨青《半山听雨贰HQ》头版限量编号[低速原抓WAV+CUE]
- 白玛多吉《云上西藏1+2》DTS-WAV
- 模拟之声慢刻CD《柏林之声3》[正版CD原抓WAV+CUE]
- 威神V(WayV)《The Highest》[FLAC/分轨][259.1MB]
- 余超颖《迷焕纪》[320K/MP3][201.15MB]
- 余超颖《迷焕纪》[FLAC/分轨][784.22MB]
- 温岚.2005-爱回温新歌加精选2CD【阿尔发】【WAV+CUE】
- 尤雅.1990-台语怀念金曲特选辑【太阳神】【WAV+CUE】
- 群星.2024-七夜雪电视剧影视原声带【听见时代】【FLAC分轨】
- 群星《胎教音乐 古典钢琴曲与水晶摇篮曲》[320K/MP3][134.14MB]
- 群星《胎教音乐 古典钢琴曲与水晶摇篮曲》[FLAC/分轨][654.13MB]
- 许惠钧《睡眠钢琴与校园民歌金曲 空灵新世纪催眠曲》[320K/MP3][201.15MB]
- wbg战队国籍分别都是哪里的 wbg战队2024阵容国籍介绍
- wbg战队教练是韩国人吗 s14wbg战队教练国籍介绍