Python教程

python-不安全的并发(同步锁)

本文主要是介绍python-不安全的并发(同步锁),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

一、为什么不安全

【1】假设a的银行账户有balance=500,此时公司像银行账户转入工资1000元,a此时又在淘宝上购买200元的商品。因为并发,如果此时银行获取balance=500,在银行系统内a的账户内就有1500元,此时该结果还没返回到a账户,这个时候淘宝也拿到了balance=500,并且减-200=300,返回到a账户内,此时balance=300;淘宝结算结束后,银行系统内的结果才返回到a账户,这个时候a账户内balance=1500

【2】不进行锁 ,则以下代码会造成输出的时候,有时候是200,有时候是1500

# -*- coding:utf-8 -*-
# __author__:pansy
# 2022/5/11

# 账户余额
import time,threading

account_balance = 500
def foo(num):
    # 需要返回最终的account_balance,因为该变量是全局变量,在局部作用域内只能声明,不能修改;如果要修改必须声明为global
    global account_balance
    # 引用账户余额,赋值给balance(引用的时候不需要将account_balance声明为global)
    balance = account_balance
    time.sleep(1)
    # balance变量要加上函数传进来的入参
    balance = balance + num
    # 返回最终的结果,此时修改了account_balance,所以要 global account_balance
    account_balance = balance

# 创建线程
t1 = threading.Thread(target=foo,args=(1000,)) # 银行打钱进来
t2 = threading.Thread(target=foo,args=(-300,)) # 淘宝消费

# 启动线程
t1.start()
t2.start()

# 需要阻塞主线程,当t1和t2线程结束后,主线程再执行打印,然后再结束主线程
t1.join()
t2.join()

# 最终余额打印
print('最终余额为:%.2f' % account_balance) # 输出可能是200.00,可能是1500.00

二、同步锁

【1】既然不安全,那只需要把重要数据balance锁住,当线程1在使用balance的时候,把balance锁定只能给该线程用;线程2被挡住无法使用balance;当线程1使用完balance后,再放开balance,线程2调用balance同时再次将balance锁住

【2】创建对象threading.Lock()

# -*- coding:utf-8 -*-
# __author__:pansy
# 2022/5/11

# 账户余额
import time,threading
# 创建锁
r = threading.Lock() # 同步锁

account_balance = 500
def foo(num):
    # 在操作重要数据前,先锁定
    r.acquire()

    # 需要返回最终的account_balance,因为该变量是全局变量,在局部作用域内只能声明,不能修改;如果要修改必须声明为global
    global account_balance
    # 引用账户余额,赋值给balance(引用的时候不需要将account_balance声明为global)
    balance = account_balance
    time.sleep(1)
    # balance变量要加上函数传进来的入参
    balance = balance + num
    # 返回最终的结果,此时修改了account_balance,所以要 global account_balance
    account_balance = balance

    # 操作完重要数据后,解锁
    r.release()

# 创建线程
t1 = threading.Thread(target=foo,args=(1000,)) # 银行打钱进来
t2 = threading.Thread(target=foo,args=(-300,)) # 淘宝消费

# 启动线程
t1.start()
t2.start()

# 需要阻塞主线程,当t1和t2线程结束后,主线程再执行打印,然后再结束主线程
t1.join()
t2.join()

# 最终余额打印
print('最终余额为:%.2f' % account_balance) # 最终输出始终为1200.00

 

这篇关于python-不安全的并发(同步锁)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!