欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-03-17 12:25:02
避开死锁 代码程序中,尽量要避免死锁的产生,下面分析常见的线程锁使用方式 ;注:只有同一把锁才会产生互斥 1、常见的死锁方式(加锁时程序报错,锁未释放): 执行上面代码,异常抛出时,锁未释放,程序卡死 2、修补代码死锁情况(抛异常处添加锁释放): 3、最佳方案(不用手动释放,即使异常也会自动释放): ......

避开死锁

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

 

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