python之多线程变量共享

因为多线程的时候,线程之间的数据共享,最大的危险是都可以来修改变量例如

import time ,threading 

balance = 0 

def change_it(n):
    global balance
    balance = balance +n
    balance = balance - n 

def run_thread(n):
    for i in range(1000000):
        change_it(n)

t1 = threading.Thread(target = run_thread , args = (5,))
t2 = threading.Thread(target = run_thread ,args = (8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

共享变量balance初始化为0 ,先加后减理论上最后的数值应该是0 ,但是经过t1,t2多次运行后balance的结果就不一定是0

代码正常运行就像下边:

t1: x1 = balance + 5 # x1 = 0 + 5 = 5
t1: balance = x1     # balance = 5
t1: x1 = balance - 5 # x1 = 5 - 5 = 0
t1: balance = x1     # balance = 0

t2: x2 = balance + 8 # x2 = 0 + 8 = 8
t2: balance = x2     # balance = 8
t2: x2 = balance - 8 # x2 = 8 - 8 = 0
t2: balance = x2     # balance = 0

结果 balance = 0

那是因为 balance = balance + n 是先将balance +n的值存进临时变量,然后在将临时变量存入balance

类似于

x = balance + n

balance = x

所以在多次加减赋值之后因为多线程的变量共享导致变量的数据改变

例如:

t1: x1 = balance + 5  # x1 = 0 + 5 = 5

t2: x2 = balance + 8  # x2 = 0 + 8 = 8
t2: balance = x2      # balance = 8

t1: balance = x1      # balance = 5
t1: x1 = balance - 5  # x1 = 5 - 5 = 0
t1: balance = x1      # balance = 0

t2: x2 = balance - 8  # x2 = 0 - 8 = -8
t2: balance = x2   # balance = -8

结果 balance = -8

所以要保证数据的正确要加锁,保证在一个线程运算时,只能由一个线程去读写。

修改如下:
import time, threading
lock = threading.Lock()
balance = 0 

def change_it(n):
    global balance
    balance = balance + n
    balance = balance - n 

def run_thread(n):
    for i in range(100000):
        lock.acquire()
        try:
                change_it(n)
        finally:
                lock.release()

t1 = threading.Thread(target=run_thread, args=(5,))
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
print(balance)

结果一直保持0

这样保证变量在调用时不会被其他的线程读写

 

原文地址:https://www.cnblogs.com/miaorn/p/11728174.html

时间: 2024-08-28 23:40:22

python之多线程变量共享的相关文章

【python】多线程编程

使用多线程编程和一个共享的数据结构如queue,这种程序任务可以用多个功能单一的线程来组织: UserRequestThread:负责读取客户的输入,可能是一个I/O信道.程序可能创建多个线程,每个客户一个,请求会被放入队列中 RequestProcessor:一个负责从队列中获取并处理请求的线程,它为下面那种线程提供输出 ReplyThread:负责把给用户的输出取出来,如果是网络应用程序就把结果发送出去,否则就保存到本地文件系统或数据库中. 一个顺序执行单线程的例子: from time i

为什么python的多线程不能利用多核CPU?

为什么python的多线程不能利用多核CPU,但是咱们在写代码的时候,多线程的确是在并发,而且还比单线程快. 一.python的多线程不能利用多核CPU? 原因: 因为GIL,python只有一个GIL,运行python时,就要拿到这个锁才能执行,在遇到I/O 操作时会释放这把锁. 如果是纯计算的程序,没有 I/O 操作,解释器会每隔100次操作就释放这把锁,让别的线程有机会 执行(这个次数可以通sys.setcheckinterval 来调整)同一时间只会有一个获得GIL线程在跑,其他线程都处

《python解释器源码剖析》第16章--python的多线程机制

16.0 序 在介绍多线程之前,我们要先知道线程是什么,线程是操作系统调度cpu工作的最小单元,同理进程则是操作系统资源分配的最小单元,线程是需要依赖于进程的,并且每一个进程只少有一个线程,这个线程我们称之为主线程.而主线程则可以创建子线程,一个进程中有多个线程去工作,我们就称之为多线程.关于线程,请记住两句话,这两句话我们在前面章节中也已经提过了. python中的一个线程,对应c语言中的一个线程,然后对应操作系统的一个线程,操作系统的线程我们一般称之为原生线程,这三者是一一对应的. pyth

python之多线程

声明:示例来源<python核心编程> 前言 单线程处理多个外部输入源的任务只能使用I/O多路复用,如:select,poll,epoll. 特别值得注意的是:由于一个串行程序需要从每个 I/O 终端通道来检查用户的输入,程序在读取 I/O 终端通道时不能阻塞,因为用户输入的到达时间是不确定的,并且阻塞会妨碍其他 I/O 通道的处理. select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责

Python学习笔记 | 变量 + 引用 + 拷贝 + 作用域

在Python中,变量是没有类型的,在使用变量的时候,不需要提前声明,只需要给这个变量赋值即可.但是,当用变量的时候,必须要给这个变量赋值:如果只写一个变量,而没有赋值,那么Python认为这个变量没有定义(not defined). 一.变量和对象 1. 可变对象和不可变对象 在Python中,对象分为两种:可变对象和不可变对象,不可变对象包括int,float,long,str,tuple等,可变对象包括list,set,dict等.需要注意的是:这里说的不可变指的是值的不可变.对于不可变类

Python中的变量引用对象需注意的几点

Python中的变量引用对象需注意的几点 分类:Python (55)  (0) 普通引用: Python中,变量的作用仅仅是一个标识,只有赋值后才被创建,它可以引用任何类型的对象,而且在引用之前必须赋值.赋值后的变量指向响应的对象,拥有该对象的空间.类型属于对象,但是不是变量. [python] view plain copy a = 3 a = "science" 上述代码说明数值3和字符串"science"分别是两种对象,初始变量a赋值对象3被创建,变量a指向

线程系列03,多线程共享数据,多线程不共享数据

多线程编程,有时希望每个线程的数据相互隔离互不影响,有时却希望线程间能共享数据,并保持同步.本篇体验多线程共享和不共享数据. □ 多线程不共享数据 对于多线程,CLR到底是怎样为它们分配内存栈空间呢?是"一个萝卜一个坑",每个线程都有自己的栈空间:还是"大树底下好乘凉",所有的线程共享同一个栈空间? 我们让2个线程执行相同的静态方法,用到相同的变量,通过打印变量来求证多线程栈空间的分配情况. class Program { static void Main(stri

c++11 多线程间共享数据 &lt;c++ concurrency in action&gt;

本章主要描述多线程之间共享数据的方法.存在问题.解决方案. 第一部分:mutex在保护共享数据中的使用 1.最简单使用: #include<mutex> std::mutex some_mutex; void func(){ some_mutex.lock(); //访问共享数据 .... some_mutex.unlock(); } 2.向lock_guard推进: 但是不推荐直接使用lock.unlock,因为unlock一定要调用,如果由于你的疏忽或前面的异常将会导致问题,再次利用RAI

JAVA学习笔记 -- 多线程之共享资源

在多线程程序运行过程中,可能会涉及到两个或者多个线程试图同时访问同一个资源.为了防止这种情况的发生,必须在线程使用共享资源时给资源"上锁",以阻挡其它线程的访问.而这种机制也常常被称为互斥量,本文主要介绍它的两种方式synchronized和Lock . 1.synchronized 当任务要执行被synchronized关键字保护的代码片段的时候,它会检查锁是否可用,然后获取锁,执行代码,释放锁.synchronized也有两种用法: A.synchronized方法 import