Python 多线程资源竞争及互斥锁

demo

import threading
import time

g_num = 0

def fun_add_01(num):
    global g_num
    for i in range(num):
        g_num += 1
    print(g_num)

def fun_add_02(num):
    global g_num
    for i in range(num):
        g_num += 1
    print(g_num)

def main():
    func_01 = threading.Thread(target=fun_add_01,args=(1000000,))
    func_02 = threading.Thread(target=fun_add_02, args=(1000000,))
    func_01.start()
    func_02.start()
    time.sleep(5)
    print(g_num)

if __name__ == '__main__':
    main()

输出结果

1130716
1262620
1262620

解析:

上述问题的产生主要是由两个函数中g_num += 1产生,g_num += 1在执行可以分为三步,

第一步:获取g_num的值

第二步: 让g_num加1

第三步:存储g_num的值

在多线程中,由于线程之间的来回切换,第一个函数中执行完第二步,还没存储到g_num中,线程切换到第二个函数中,此时函数1完成了加1的动作,但g_num传到第二个函数中的值却是没有发生变化的,此时在函数2中继续进行上述操作,当函数2可能完成加1的动作后再次切换到函数1,此时函数1的+1值才会计入到g_num中。由于两个函数不断切换导致许多+1的动作完成后,其值并未计入到内存中,最后导致结果出错

解决方法:

使用互斥锁,互斥锁里面的代码在执行的时候,进程不会切换

互斥锁使用

mutex = threading.Lock()
mutex.acquire()
# 执行代码
mutex.release()

死锁的产生

mutex1 = threading.Lock()
mutex2 = threading.Lock()

线程1
mutex1.acquire()
mutex2.acquire()
# 执行代码
mutex2.release()
mutex1.release()

线程2
mutex2.acquire()
mutex1.acquire()
# 执行代码
mutex1.release()
mutex2.release()

此时,锁1等待锁2解开,锁2等待锁1解开,最终造成了堵塞

避免死锁的方法

1 设置超时时间

2 银行家算法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值