Python开发【笔记】:加锁的最佳方案

避开死锁

代码程序中,尽量要避免死锁的产生,下面分析常见的线程锁使用方式 ;注:只有同一把锁才会产生互斥

1、常见的死锁方式(加锁时程序报错,锁未释放):

import time
import threading

class Lock():
    def __init__(self):
        self.mutex = threading.Lock()

    def error(self):
        try:
            self.mutex.acquire()
            a = '1'
            b = 2
            print(a+b)
            self.mutex.release()
        except Exception as e:
            print(e)

    def safe(self):
        try:
            self.mutex.acquire()
            a = 1
            b = 2
            print(a + b)
            self.mutex.release()
        except Exception as e:
            print(e)

def func1(cls):
    while True:
        cls.safe()
        time.sleep(0.1)

def func2(cls):
    while True:
        cls.error()
        time.sleep(0.1)

if __name__ == '__main__':
    lock = Lock()
    t1 = threading.Thread(target=func1,args=(lock,))
    t1.start()
    t2 = threading.Thread(target=func2,args=(lock,))
    t2.start()

# 3
# must be str, not int

执行上面代码,异常抛出时,锁未释放,程序卡死

2、修补代码死锁情况(抛异常处添加锁释放):

import time
import threading

class Lock():
    def __init__(self):
        self.mutex = threading.Lock()

    def error(self):
        try:
            self.mutex.acquire()
            a = '1'
            b = 2
            print(a+b)
            self.mutex.release()
        except Exception as e:
            print(e)
            self.mutex.release()

    def safe(self):
        try:
            self.mutex.acquire()
            a = 1
            b = 2
            print(a + b)
            self.mutex.release()
        except Exception as e:
            print(e)

def func1(cls):
    while True:
        cls.safe()
        time.sleep(0.1)

def func2(cls):
    while True:
        cls.error()
        time.sleep(0.1)

if __name__ == '__main__':
    lock = Lock()
    t1 = threading.Thread(target=func1,args=(lock,))
    t1.start()
    t2 = threading.Thread(target=func2,args=(lock,))
    t2.start()

# 3
# must be str, not int
# must be str, not int
# 3
# 3

3、最佳方案(不用手动释放,即使异常也会自动释放):

import time
import threading

class Lock():
    def __init__(self):
        self.mutex = threading.Lock()

    def error(self):
        try:
            with self.mutex:
                a = '1'
                b = 2
                print(a+b)
        except Exception as e:
            print(e)

    def safe(self):
        try:
            with self.mutex:
                a = 1
                b = 2
                print(a + b)
        except Exception as e:
            print(e)

def func1(cls):
    while True:
        cls.safe()
        time.sleep(0.1)

def func2(cls):
    while True:
        cls.error()
        time.sleep(0.1)

if __name__ == '__main__':
    lock = Lock()
    t1 = threading.Thread(target=func1,args=(lock,))
    t1.start()
    t2 = threading.Thread(target=func2,args=(lock,))
    t2.start()

# 3
# must be str, not int
# 3
# must be str, not int
# 3
# must be str, not int

相关推荐