Python 多线程共享变量的实现示例
多线程-共享全局变量
#coding=utf-8 fromthreadingimportThread importtime g_num=100 defwork1(): globalg_num foriinrange(3): g_num+=1 print("----inwork1,g_numis%d---"%g_num) defwork2(): globalg_num print("----inwork2,g_numis%d---"%g_num) print("---线程创建之前g_numis%d---"%g_num) t1=Thread(target=work1) t1.start() #延时一会,保证t1线程中的事情做完 time.sleep(1) t2=Thread(target=work2) t2.start()
执行如下:
[root@server01many_task]#pythontest5.py
---线程创建之前g_numis100---
----inwork1,g_numis103---
----inwork2,g_numis103---
[root@server01many_task]#
从上面两个线程执行的结果来看,线程t1将g_num加到103,在线程t2也是打印g_num=103。所以对于两个线程,g_num这个全局变量是共享的。
列表当做实参传递到线程中
#coding=utf-8 fromthreadingimportThread importtime defwork1(nums): nums.append(44) print("----inwork1---",nums) defwork2(nums): #延时一会,保证t1线程中的事情做完 time.sleep(1) print("----inwork2---",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@server01many_task]#pythontest6.py
('----inwork1---',[11,22,33,44])
('----inwork2---',[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@server01many_task]#vimtest4.py #coding=utf-8 importthreading fromtimeimportsleep,ctime #初始化g_num g_num=0 defadd_func1(num): globalg_num foriinrange(num): g_num+=1 print("add_func1,第%d次,g_num等于%d"%(i,g_num)) #sleep(0.5) defadd_func2(num): globalg_num foriinrange(num): g_num+=1 print("add_func2,第%d次,g_num等于%d"%(i,g_num)) #sleep(0.5) defmain(): #执行线程 t1=threading.Thread(target=add_func1,args=(100,)) t2=threading.Thread(target=add_func2,args=(100,)) t1.start() t2.start() #判断当线程存在,则等待1秒 whilelen(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@server01many_task]#
两个线程虽然执行很快,但是g_num恰好就是100+100=200的结果,是正确的。不过,这个数量少,可能看不出问题来。
测试示例2
[root@server01many_task]#vimtest7.py defwork1(num): globalg_num foriinrange(num): g_num+=1 print("----inwork1,g_numis%d---"%g_num) defwork2(num): globalg_num foriinrange(num): g_num+=1 print("----inwork2,g_numis%d---"%g_num) print("---线程创建之前g_numis%d---"%g_num) t1=threading.Thread(target=work1,args=(10000000,)) t1.start() t2=threading.Thread(target=work2,args=(10000000,)) t2.start() whilelen(threading.enumerate())!=1: time.sleep(1) print("2个线程对同一个全局变量操作之后的最终结果是:%s"%g_num)
运行如下:
[root@server01many_task]#pythontest7.py
---线程创建之前g_numis0---
----inwork1,g_numis11977799---
----inwork2,g_numis19108796---
2个线程对同一个全局变量操作之后的最终结果是:19108796
[root@server01many_task]#
正确的结果应该是:20000000
结论
如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
到此这篇关于Python多线程共享变量的实现示例的文章就介绍到这了,更多相关Python多线程共享变量内容请搜索毛票票以前的文章或继续浏览下面的相关文章希望大家以后多多支持毛票票!