Python 多线程共享变量的实现示例
作者:DevOps海洋的渔夫 发布时间:2022-12-17 09:39:10
多线程-共享全局变量
#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
结论
如果多个线程同时对同一个全局变量操作,会出现资源竞争问题,从而数据结果会不正确
来源:https://www.jianshu.com/p/44b94dcad5c9


猜你喜欢
- 1.开发环境 vue+element2.电脑系统 windows 10 专业版3.在开发的过程中,我们总是会使用到 git管理代码!使用方法
- request库是python的第三方库,它也是目前公认的爬取网页最好的第三方库,其特点是:简单、简洁,甚至用一行代码就能从网页上获取相关资
- 正则表达式是处理字符串的强大工具。作为一个概念而言,正则表达式对于Python来说并不是独有的。但是,Python中的正则表达式在实际使用过
- 作为 Web 设计者,我们希望实现鹤立鸡群的设计,要做到这一点,要开阔眼界。欧美同东方的 Web 设计很不同,因为属于不同的文化。韩国不仅为
- 1、序列(拆包)*用作序列拆包:*可对字符串、列表、集合、元组、字典、数字元素等序列进行拆包print(*(1,2,3,4,5,6))#1
- API:statuses/public_timeline 返回最新的200条公共微博,返回结果非完全实时CODE:#!/usr/
- Facebook的网站速度做为最关键的公司任务之一。在2009年,我们成功地实现了Facebook网站速度提升两倍 。而正是我们的工程师团队
- 1。在Asp页面首部<head>加入 Response.Buffer =
- 在做维护项目的时,我们经常会遇到索引维护的问题,通过语句,我们就可以判断某个表的索引是否需要重建。 执行一下语句:先分析表的索引 分析表的索
- ZeroClipboard.js是一个支持复制和粘贴的JavaScript插件,目前官方已经到2.x的版本了,但不支持IE9以下的浏览器,而
- /* Cookie Library -- "Night of the Living Cookie" Version (2
- 1、问题描述在用yolov3训练自己的数据集时,尝试加载预训练的权重,在冻结前154层的基础上,利用自己的数据集finetune。出现如下错
- HTTPX是Python3的功能齐全的HTTP客户端,它提供同步和异步API,并支持HTTP/1.1和HTTP/2安装pip install
- 在做语义分割项目时,标注的图片不合标准,而且类型是RGBA型,且是A的部分表示的类别,因此需要将该图片转化为RGB图片# -*- codin
- 一、先来看看Python星空图代码绘制成品1 两个人的星空星空下,欲执子之手,相倚长青树。看皎洁月色,闻乡间气息,赏佳人芳心。2 明月相伴的
- 本文实例讲述了python实现自动更换ip的方法。分享给大家供大家参考。具体实现方法如下:#!/usr/bin/env python#-*-
- --******************************************************* --* 清空所有表中的数
- 查找出SQLServer的死锁和阻塞的源头 --查找出SQLServer死锁和阻塞的源头use mastergodeclare @spid
- 今天在开发一个手机短信通讯录的前端界面时,界面中使用了checkbox,来做为各项的选择控件,但是操作时,除了点差子。由于逻辑需要,需要预先
- 给定一个字典,然后按键(key)或值(value)对字典进行排序。def dictionairy(): &nbs