Python 多线程 - 共享变量(python编程)

网友投稿 428 2022-08-26


Python 多线程 - 共享变量(python编程)

仅用学习参考

多线程-共享全局变量

#coding=utf-8from threading import Threadimport timeg_num = 100def 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-8from threading import Threadimport timedef 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-8import threadingfrom time import sleep,ctime# 初始化g_numg_num = 0def 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等于197add_func2,第97次,g_num等于198add_func2,第98次,g_num等于199add_func2,第99次,g_num等于2002个线程对同一个全局变量操作之后的最终结果是: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​​

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Python 多线程 - 同步、互斥锁、死锁、银行家算法(python下载安装教程)
下一篇:SpringBoot实现PPT格式文件上传并在线预览功能
相关文章

 发表评论

暂时没有评论,来抢沙发吧~