多线程死锁问题及解决办法

发布时间 2023-03-30 14:55:43作者: MrSphere

什么是线程

  1. 进程其实不是一个执行单位,进程是一个资源单位

  2. 每个进程内自带一个线程,线程才是cpu上的执行单位

    如果把操作系统比喻为一座工厂
    在工厂内每造出一个车间 ===》启动一个进程
    每个车间内至少有一条流水线 ===》每个进程内至少有一个线程
    线程=》单指代码的执行过程
    进程-》资源的申请与销毁的过程

进程vs线程

  1. 内存共享or隔离
    多个进程内存空间彼此隔离
    同一进程下的多个线程共享该进程内的数据

  2. 创建速度
    造线程的速度要远远快于造进程

'''
deathLock
CPython 实现细节: 在 CPython 中,由于存在 全局解释器锁,同一时刻只有一个线程可以执行 Python 代码
(虽然某些性能导向的库可能会去除此限制)。 如果你想让你的应用更好地利用多核心计算机的计算资源,
推荐你使用 multiprocessing 或 concurrent.futures.ProcessPoolExecutor。
但是,如果你想要同时运行多个 I/O 密集型任务,则多线程仍然是一个合适的模型。
'''
import threading
import time
from threading import Thread, Lock

mutexA = Lock()
mutexB = Lock()


class Mythread(Thread):
    def run(self) -> None:
        self.f1()
        # self.f2()
        self.f3()

    def f1(self):
        mutexA.acquire()
        print(f"{self.name} get the lockA ")
        mutexB.acquire()
        print(f"{self.name} get the lockB ")
        time.sleep(1)
        mutexB.release()
        print(f"{self.name} release the lockB ")
        mutexA.release()
        print(f"{self.name} release the lockA ")

    # def f2(self):
    #     # 只有1把锁不会死锁,有两把锁同时抢就会锁住
    #     mutexB.acquire()
    #     print(f"{self.name} get the lockB ")
    #     mutexA.acquire()
    #     time.sleep(1)
    #     print(f"{self.name} get the lockA ")
    #     mutexA.release()
    #     print(f"{self.name} release the lockA ")
    #     mutexB.release()
    #     print(f"{self.name} release the lockB ")

    def f3(self):
        # 只有1把锁不会死锁,有两把锁同时抢就会锁住
        mutexB.acquire()
        print(f"{self.name} get the lockB ")
        mutexA.release()
        print(f"{self.name} release the lockA ")

        time.sleep(1)
        mutexA.acquire()
        print(f"{self.name} get the lockA ")
        mutexB.release()
        print(f"{self.name} release the lockB ")


if __name__ == '__main__':
    for i in range(10):
        t = Mythread()
        t.start()
        # 当线程太多,而线程中执行函数体内的全局锁太少时,并且在不同线程中调用两把锁,就会发生死锁现象,线程会继续执行
        # 锁是全局变量,独一无二的
    print(threading.active_count())

from threading import Thread, RLock

the solution of deathlock
# -*- coding: utf-8 -*-
'''
'''
import threading
import time
from threading import Thread, RLock

# pay attention, there should be an object for 2 variables
obj = RLock()
mutexA = obj
mutexB = obj