多线程-共享全局变量

多线程-共享全局变量

import threading
import time g_num = 200 def test1():
global g_num
for i in range(5):
g_num += 1
print("--test1, g_num = %d--" % g_num) def test2():
global g_num
print("--test2, g_num = %d--" % g_num) if __name__ == "__main__": print("--执行线程之前, g_num = %d--" % g_num) t1 = threading.Thread(target=test1)
t1.start() # 延时一会儿,确保线程t1中的事情能做
time.sleep(1) t2 = threading.Thread(target=test2)
t2.start()

运行结果:

--执行线程之前, g_num = 200--
--test1, g_num = 205--
--test2, g_num = 205--

在上面的程序中。test1函数循环五次,每次将g_num全局变量加一并打印g_num的值,在test2函数中仅仅打印g_num的值。在t1线程中执行test1函数,在t2线程中执行test2函数,并在执行t2线程之前,延时一秒中来保证t1线程执行完毕。

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

import threading
import time def test1(nums):
nums.append(54)
print("--test1, nums=", nums) g_nums = [1, 8, 9] def test2(nums): # 确保test1中执行完毕
time.sleep(1)
print("--test2, nums=", nums) if __name__ == "__main__": t1 = threading.Thread(target=test1, args=(g_nums,))
t1.start() t2 = threading.Thread(target=test2, args=(g_nums,))
t2.start()

运行结果:

--test1, nums= [1, 8, 9, 54]
--test2, nums= [1, 8, 9, 54]

总结

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

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

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

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

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

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

测试1

import threading
import time g_num = 0 def test1(num):
global g_num
for i in range(num):
g_num += 1
print("--test1, g_num = %d--" % g_num) def test2(num):
global g_num
for i in range(num):
g_num += 1
print("--test2, g_num = %d--" % g_num) if __name__ == "__main__": print("--创建线程之前, g_num = %d--" % g_num) t1 = threading.Thread(target=test1, args=(100,))
t1.start() t2 = threading.Thread(target=test2, args=(100,))
t2.start() while len(threading.enumerate()) != 1:
time.sleep(1) print("最终结果为:g_num=%d" % g_num)

运行结果:

--创建线程之前, g_num = 0--
--test1, g_num = 100--
--test2, g_num = 200--
最终结果为:g_num=200

测试2

在测试1的基础上,向test1和test2方法传入的参数的值为:9999999

运行结果:

--创建线程之前, g_num = 0--
--test1, g_num = 13554011--
--test2, g_num = 13571206--
最终结果为:g_num=13571206

很显然,期待的结果为:9999999 + 9999999 = 19999998,而运行结果为:13571206。

python多线程-共享全局变量的更多相关文章

  1. 一起学Python: 多线程-共享全局变量问题

    多线程-共享全局变量问题 多线程开发可能遇到的问题 假设两个线程t1和t2都要对全局变量g_num(默认是0)进行加1运算,t1和t2都各对g_num加10次,g_num的最终的结果应该为20. 但是 ...

  2. 一起学Python:多线程-共享全局变量

    多线程-共享全局变量 from threading import Thread import time g_num = 100 def work1(): global g_num for i in r ...

  3. python 多线程共享全局变量的问题

    多线程都是在同一个进程中运行的.因此在进程中的全局变量所有线程都是可共享的. 这就造成了一个问题,因为线程执行的顺序是无序的.有可能会造成数据错误. 直白理解:也就是多线程执行的时候,同时对一个全局变 ...

  4. 7.Python网络编程_多线程共享全局变量问题

    Python多线程支持全局变量的共享操作,但是它存在很多问题,先来看以下程序,该程序理论上执行完毕后全局变量g_num的值应该是2000000,但是在实际运行中,结果不足理论值 import thre ...

  5. Python 中多线程共享全局变量的问题

    写在前面不得不看的一些P话: Python 中多个线程之间是可以共享全局变量的数据的. 但是,多线程共享全局变量是会出问题的. 假设两个线程 t1 和 t2 都要对全局变量g_num (默认是0)进行 ...

  6. python编程系列---多线程共享全局变量出现了安全问题的解决方法

    多线程共享全局变量出现了安全问题的解决方法 当多线程共享全局变量时,可能出现安全问题,解决机制----互斥锁:即在在一段与全局变量修改相关的代码中,假设一个时间片不足以完成全局变量的修改,就在这段代码 ...

  7. 多任务-python实现-多线程共享全局变量(2.1.3)

    @ 目录 1.全局变量的修改 2.全局变量在多线程中的共享 3.多线程可能遇到的问题 1.全局变量的修改 代码实现 num = 100 nums = [11,22] def test(): globa ...

  8. python 多进程共享全局变量之Manager()

    Manager支持的类型有list,dict,Namespace,Lock,RLock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value和A ...

  9. python多线程详解

    目录 python多线程详解 一.线程介绍 什么是线程 为什么要使用多线程 二.线程实现 threading模块 自定义线程 守护线程 主线程等待子线程结束 多线程共享全局变量 互斥锁 递归锁 信号量 ...

随机推荐

  1. 在使用可变数组过程中遇到*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFDictionary setObject:forKey:]: mutating method sent to immutable object'问题

    *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFD ...

  2. Redis-06.Cluster

    Redis Cluster是一个高性能高可用的分布式系统.由多个Redis实例组成的整体,数据按照一致性哈希算法存储分布在多个Redis实例上,并对使用虚拟槽(Slot)对一致性哈希算法进行改进,通过 ...

  3. 【webpack】流行的前端模块化工具webpack初探

    从开发文件到生产文件   有一天我突然意识到一个问题,在使用react框架搭建应用时,我使用到了sass/less,JSX模版以及ES6的语法在编辑器下进行开发,使用这些写法是可以提高开发的效率.可是 ...

  4. MapReduce多种join实现实例分析(二)

    上一篇<MapReduce多种join实现实例分析(一)>,大家可以点击回顾该篇文章.本文是MapReduce系列第二篇. 一.在Map端进行连接使用场景:一张表十分小.一张表很大.用法: ...

  5. Linux rpm包安装不了

    有时候会发现安装rpm包时会报错,解决办法: 到rpm包所在目录执行 createrepo -v ./   这个命令 然后会生成一个repodate这个目录,然后在进行安装rpm就可以了!

  6. iTerm2 使用笔记

    iTerm2 使用了1年多了,一些功能其实还没有主动去发现,这次接着项目忙完的空闲时间整理一下tips,提高工作效率,方便以后查阅. 一.几个术语 从小到大:session > pane > ...

  7. 涨姿势:Spring Boot 2.x 启动全过程源码分析

    目录 SpringApplication 实例 run 方法运行过程 总结 上篇<Spring Boot 2.x 启动全过程源码分析(一)入口类剖析>我们分析了 Spring Boot 入 ...

  8. websocket ----简介,以及demo

    #导报 from dwebsocket.decorators import accept_websocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户 ...

  9. 深度解析使用CSS单位px、em、rem、vh、vw、vmin、vmax实现页面布局

     1.px:绝对单位,页面按精确像素展示 2.em:相对单位,基准点为父节点字体的大小,如果自身定义了font-size按自身来计算(浏览器默认字体是16px),整个页面内1em不是一个固定的值. e ...

  10. 课程五(Sequence Models),第三周(Sequence models & Attention mechanism) —— 0.Practice questions:Sequence models & Attention mechanism