python—互斥锁与死锁

互斥锁

一.概念原理

当多个线程几乎同时修改某一个共享数据的时候,需要进行同步控制

线程同步能够保证多个线程安全访问竞争资源,最简单的同步机制是引入互斥锁。

互斥锁为资源引入一个状态:锁定/非锁定。

某个线程要更改共享数据时,先将其锁定,此时资源的状态为“锁定”,其他线程不能更改;直到该线程释放资源,将资源的状态变成“非锁定”,其他的线程才能再次锁定该资源。互斥锁保证了每次只有一个线程进行写入操作,从而保证了多线程情况下数据的正确性。

二.示例

from threading import Thread
from threading import Lock
g_num = 0
#创建一个全局锁对象
lock= Lock()

def work1(num):
    global g_num
    lock.acquire()#加锁
    for i in range(num):
        g_num+=1
    lock.release()#解锁
    print("in work1-->",g_num)

def work2(num):
    global g_num
    lock.acquire()#加锁
    for i in range (num):
        g_num+=1
    lock.release()#解锁
    print("work2-->",g_num)

def main():
    t1 = Thread(target=work1,args=(1000000,))
    t2 = Thread(target=work2, args=(1000000,))
    t1.start()
    t2.start()
    t2.join()

if __name__ == '__main__':

    main()
    print("main-->",g_num)

结果:

in work1--> 1000000
work2--> 2000000
main--> 2000000

其中,
锁定方法acquire可以有一个参数。

如果参数设定为True,则当前线程会堵塞,直到获取到这个锁为止(如果没有指定,那么默认为True)
如果设定参数为False,则当前线程不会堵塞

锁的好处:

确保了某段关键代码只能由一个线程从头到尾完整地执行

锁的坏处:

阻止了多线程并发执行,包含锁的某段代码实际上只能以单线程模式执行,效率就大大地下降了
由于可以存在多个锁,不同的线程持有不同的锁,并试图获取对方持有的锁时,可能会造成死锁

死锁

一.概念

在多道程序系统中,由于多个进程的并发执行,改善了系统资源的利用率并提高了系统的处理能力。

然而,多个进程的并发执行也带来了新的问题——死锁。所谓死锁是指多个进程因竞争资源而造成的一种僵局,若无外力作用,这些进程都将无法向前推进。

二.示例


lock1 = Lock()
lock2 = Lock()

def work1(num):
    lock1.acquire()#lock1上锁
    time.sleep(1)
    print("in work1")
    lock2.acquire()  # lock2上锁
    print("work1-----")
    lock2.release()#lock2解锁
    lock1.release()#lock1解锁

def work2(num):
    lock2.acquire()#lock2加锁
    print("in work2")
    lock1.acquire()#lock1加锁
    print("work1-----")
    lock1.release()#lock1解锁
    lock2.release()#lock2解锁

if __name__ == '__main__':
    t1 = Thread(target=work1,args=(1000000,))
    t2 = Thread(target=work2, args=(1000000,))
    t1.start()
    t2.start()

结果:

in work2
in work1

看了上面的例子我们来说说防止死锁的加锁机制

问题:
你正在写一个多线程程序,其中线程需要一次获取多个锁,此时如何避免死锁问题。
解决方案:
在多线程程序中,死锁问题很大一部分是由于线程同时获取多个锁造成的。举个例子:一个线程获取了第一个锁,然后在获取第二个锁的 时候发生阻塞,那么这个线程就可能阻塞其他线程的执行,从而导致整个程序假死。 解决死锁问题的一种方案是为程序中的每一个锁分配一个唯一的id,然后只允许按照升序规则来使用多个锁。

发布了36 篇原创文章 · 获赞 49 · 访问量 2872

猜你喜欢

转载自blog.csdn.net/HENG302926/article/details/104282888