Python开发【笔记】:加锁的最佳方案
程序员文章站
2023-12-31 08:30:22
避开死锁 代码程序中,尽量要避免死锁的产生,下面分析常见的线程锁使用方式 ;注:只有同一把锁才会产生互斥 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