python -线程锁

1. 为什么需要线程锁?

多个线程对同一个数据进行修改时, 可能会出现不可预料的情况.

2. 如何实现线程锁?

    # 1. 实例化一个锁对象;
        lock = threading.Lock()
    # 2. 操作变量之前进行加锁
        lock.acquire()
    # 3. 操作变量之后进行解锁
        lock.release()

python多线程是并发执行,有可能会出现错误
并发: 交替执行
并行: 同时执行
多线程和多进程最大的不同在于,多进程中,同一个变量,各自有一份拷贝存在于每个进程中,互不影响,而多线程中,所有变量都由所有线程共享,所以,任何一个变量都可以被任何一个线程修改,因此,线程之间共享数据最大的危险在于多个线程同时改一个变量,把内容给改乱了。

锁的好处就是确保了某段关键代码只能由一个线程从头到尾完整地执行,坏处当然也很多,首先是阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了。 其次,由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁,导致多个线程全部挂起,既不能执行,也无法结束,只能靠
操作系统强制终止。

先看一个没有加线程锁错误的存钱取钱的例子:

import threading

def add():
    global money
    for i in range(1000000):
        money += 1

def reduce():
    global money
    for i in range(1000000):
        money -=1

if __name__ == '__main__':
    money = 0

    # lock = threading.Lock()

    t1 = threading.Thread(target=add)
    t2 = threading.Thread(target=reduce)

    t1.start()
    t2.start()
    t1.join()
    t2.join()
    print('当前金额:',money)

在计算量比较大时容易出现错误,存1000000取1000000当前金额应该是0.结果运行很多次却是负数明显错误了。
在这里插入图片描述加上线程锁
方法一:threading.Thread

import threading


#  银行存钱和取钱
def add(lock):
    global money  # 生命money为全局变量
    for i in range(1000000):
        # 2. 操作变量之前进行加锁
        lock.acquire()
        money += 1  # money;  money+1; money=money+1;
        # 3. 操作变量之后进行解锁
        lock.release()


def reduce(lock):
    global money
    for i in range(1000000):
        # 2. 操作变量之前进行加锁
        lock.acquire()
        money -= 1
        # 3. 操作变量之后进行解锁
        lock.release()


if __name__ == '__main__':
    money = 0
    # 1. 实例化一个锁对象;
    lock = threading.Lock()

    t1 = threading.Thread(target=add, args=(lock,))
    t2 = threading.Thread(target=reduce, args=(lock,))
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print("当前金额:", money)

在这里插入图片描述
无论运行多少次结果都是0

方法二:
重写run方法

import threading


#  银行存钱和取钱

class AddThread(threading.Thread):
    def __init__(self,lock):
        super(AddThread,self).__init__()
        self.lock = lock

    def run(self):
        global money  # 生命money为全局变量
        for i in range(1000000):
            # 2. 操作变量之前进行加锁
            self.lock.acquire()
            money += 1  # money;  money+1; money=money+1;
            # 3. 操作变量之后进行解锁
            self.lock.release()

class ReduceThread(threading.Thread):
    def __init__(self,lock):
        super(ReduceThread,self).__init__()
        self.lock = lock
    def run(self):
        global money
        for i in range(1000000):
            # 2. 操作变量之前进行加锁
            self.lock.acquire()
            money -= 1
            # 3. 操作变量之后进行解锁
            self.lock.release()


if __name__ == '__main__':
    money = 0
    # 1. 实例化一个锁对象;
    lock = threading.Lock()
    # 重写run方法通过新写的类AddThread、ReduceThread实例化对象
    # t1 = threading.Thread(target=add, args=(lock,))
    # t2 = threading.Thread(target=reduce, args=(lock,))
    t1 = AddThread(lock)
    t2 = ReduceThread(lock)
    t1.start()
    t2.start()
    t1.join()
    t2.join()

    print("当前金额:", money)

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值