📜  操作系统中的死锁 (1)

📅  最后修改于: 2023-12-03 14:54:46.713000             🧑  作者: Mango

操作系统中的死锁

什么是死锁?

死锁指的是在多个进程中,每个进程都在等待另一个进程所占有的资源,导致所有的进程都无法继续执行下去的一种情况。

何种情况下会出现死锁?

死锁通常发生在以下情况:

  • 多个进程需要使用同一个资源,但是资源只能被一个进程占用。
  • 进程持有某些资源,并请求其他进程持有的资源。
  • 进程在等待资源的同时,仍继续占有自己所持有的资源。
如何避免死锁?

为了避免死锁的发生,可以采取以下措施:

  • 破坏"请求和保持"条件。在进程请求资源时,要求其先释放已经占有的资源,再申请新资源。
  • 破坏"不可剥夺"条件。当某些进程持有资源时,如果其他进程请求这些资源,就要把原先进程所占有的资源“夺取”过来,让其他进程使用。
  • 破坏“循环等待”条件。按照某一顺序分配资源,所有进程按照这个顺序请求资源,就不会产生循环等待的情况。

以上三个措施称为死锁预防。

另外,还有死锁避免和死锁恢复两种策略。死锁避免是在资源分配前判断是否会导致死锁,如果会就拒绝分配。死锁恢复则是在死锁发生后,采取一些措施,比如回滚进程,强制终止进程等。

代码示例

下面是一个简单的死锁示例,两个线程都在等待对方释放资源。

import threading

# 创建两个锁
locka = threading.Lock()
lockb = threading.Lock()

def thread1():
    locka.acquire()
    print('thread1 get locka')
    lockb.acquire()
    print('thread1 get lockb')
    lockb.release()
    locka.release()
    print('thread1 release lock')

def thread2():
    lockb.acquire()
    print('thread2 get lockb')
    locka.acquire()
    print('thread2 get locka')
    locka.release()
    lockb.release()
    print('thread2 release lock')

# 创建两个线程并启动
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t1.start()
t2.start()
t1.join()
t2.join()

以上代码会产生死锁。为了避免死锁,我们可以使用with语句自动管理锁的获取和释放。

import threading

# 创建两个锁
locka = threading.Lock()
lockb = threading.Lock()

def thread1():
    with locka:
        print('thread1 get locka')
        with lockb:
            print('thread1 get lockb')
    print('thread1 release lock')

def thread2():
    with lockb:
        print('thread2 get lockb')
        with locka:
            print('thread2 get locka')
    print('thread2 release lock')

# 创建两个线程并启动
t1 = threading.Thread(target=thread1)
t2 = threading.Thread(target=thread2)
t1.start()
t2.start()
t1.join()
t2.join()

使用with语句自动释放锁,可以避免死锁的发生。