multithreading 什么是死锁?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34512/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 00:57:46  来源:igfitidea点击:

What is a deadlock?

multithreadingconcurrencylockingdeadlock

提问by bmurphy1976

When writing multi-threaded applications, one of the most common problems experienced are deadlocks.

编写多线程应用程序时,遇到的最常见问题之一是死锁。

My questions to the community are:

我向社区提出的问题是:

  1. What is a deadlock?

  2. How do you detect them?

  3. Do you handle them?

  4. And finally, how do you prevent them from occurring?

  1. 什么是死锁?

  2. 你如何检测它们?

  3. 你处理他们吗?

  4. 最后,您如何防止它们发生?

回答by Keith

A lockoccurs when multiple processes try to access the same resource at the same time.

当多个进程试图同时访问同一资源时。

One process loses out and must wait for the other to finish.

一个进程失败,必须等待另一个进程完成。

A deadlockoccurs when the waiting process is still holding on to another resource that the first needs before it can finish.

一个死锁时,等待的过程中仍保存到另一个资源,它所收到的第一需要,可以完成发生。

So, an example:

所以,一个例子:

Resource A and resource B are used by process X and process Y

资源 A 和资源 B 被进程 X 和进程 Y 使用

  • X starts to use A.
  • X and Y try to start using B
  • Y 'wins' and gets B first
  • now Y needs to use A
  • A is locked by X, which is waiting for Y
  • X 开始使用 A。
  • X 和 Y 尝试开始使用 B
  • Y'赢'并先得到 B
  • 现在 Y 需要使用 A
  • A 被 X 锁定,X 正在等待 Y

The best way to avoid deadlocks is to avoid having processes cross over in this way. Reduce the need to lock anything as much as you can.

避免死锁的最好方法是避免进程以这种方式交叉。尽可能减少锁定任何东西的需要。

In databases avoid making lots of changes to different tables in a single transaction, avoid triggers and switch to optimistic/dirty/nolock reads as much as possible.

在数据库中,避免在单个事务中对不同表进行大量更改,避免触发器并尽可能切换到乐观/脏/非锁定读取。

回答by Levent Divilioglu

Let me explain a real world (not actually real) example for a deadlock situation from the crime movies. Imagine a criminal holds an hostage and against that, a cop also holds an hostage who is a friend of the criminal. In this case, criminal is not going to let the hostage go if cop won't let his friend to let go. Also the cop is not going to let the friend of criminal let go, unless the criminal releases the hostage. This is an endless untrustworthy situation, because both sides are insisting the first step from each other.

让我解释一个真实世界(实际上不是真实的)犯罪电影中僵局情况的例子。想象一下,一名罪犯劫持了人质,而与之相反,一名警察也劫持了一名作为罪犯朋友的人质。在这种情况下,如果警察不让他的朋友放人,罪犯就不会放人质。此外,除非罪犯释放人质,否则警察不会让罪犯的朋友放手。这是一个无休止的不信任局面,因为双方都在坚持彼此的第一步。

Criminal & Cop Scene

犯罪和警察场景

enter image description here

在此处输入图片说明

So simply, when two threads needs two different resources and each of them has the lock of the resource that the other need, it is a deadlock.

简单来说,当两个线程需要两个不同的资源,并且每个线程都拥有另一个需要的资源的锁时,就是死锁。

Another High Level Explanation of Deadlock : Broken Hearts

死锁的另一个高级解释:破碎的心

You are dating with a girl and one day after an argument, both sides are heart-broken to each other and waiting for an I-am-sorry-and-I-missed-youcall. In this situation, both sides want to communicate each other if and only if one of them receives an I-am-sorrycall from the other. Because that neither of each is going to start communication and waiting in a passive state, both will wait for the other to start communication which ends up in a deadlock situation.

你正在和一个女孩约会,在争吵后的一天,双方都心碎了,等待着一个对不起,我想念你的电话。在这种情况下,当且仅当其中一方收到另一方的“对不起”电话,双方都希望相互通信。因为双方都不会开始通信并处于被动状态等待,所以双方都会等待对方开始通信,最终陷入死锁状态。

回答by Mats Fredriksson

Deadlocks will only occur when you have two or more locks that can be aquired at the same time and they are grabbed in different order.

只有当您有两个或多个可以同时获取的锁并且它们以不同的顺序被抓取时,才会发生死锁。

Ways to avoid having deadlocks are:

避免死锁的方法有:

  • avoid having locks (if possible),
  • avoid having more than one lock
  • always take the locks in the same order.
  • 避免使用锁(如果可能),
  • 避免拥有多个锁
  • 始终以相同的顺序取锁。

回答by Varun

To define deadlock, first I would define process.

要定义死锁,首先我要定义进程。

Process:As we know process is nothing but a programin execution.

流程正如我们所知,流程只不过是一个program执行过程。

Resource:To execute a program process needs some resources. Resource categories may include memory, printers, CPUs, open files, tape drives, CD-ROMS, etc.

资源执行程序进程需要一些资源。资源类别可能包括内存、打印机、CPU、打开的文件、磁带驱动器、CD-ROM 等。

Deadlock:Deadlock is a situation or condition when two or more processes are holding some resources and trying to acquire some more resources, and they can not release the resources until they finish there execution.

死锁死锁是一种情况或条件,当两个或多个进程持有一些资源并试图获取更多资源时,它们在完成执行之前无法释放资源。

Deadlock condition or situation

死锁条件或情况

enter image description here

在此处输入图片说明

In the above diagram there are two process P1and p2and there are two resources R1and R2.

在上图中,有两个进程P1p2,并且有两个资源R1R2

Resource R1is allocated to process P1and resource R2is allocated to process p2. To complete execution of process P1needs resource R2, so P1request for R2, but R2is already allocated to P2.

资源R1分配给进程P1,资源R2分配给进程p2。为了完成进程P1 的执行需要资源R2,所以P1请求R2,但R2已经分配给P2

In the same way Process P2to complete its execution needs R1, but R1is already allocated to P1.

同样,进程P2完成其执行需要R1,但R1已经分配给P1

both the processes can not release their resource until and unless they complete their execution. So both are waiting for another resources and they will wait forever. So this is a DEADLOCKCondition.

两个进程在完成执行之前都不能释放它们的资源。所以两者都在等待另一种资源,他们将永远等待。所以这是一个死锁条件。

In order for deadlock to occur, four conditions must be true.

为了发生死锁,必须满足四个条件。

  1. Mutual exclusion- Each resource is either currently allocated to exactly one process or it is available. (Two processes cannot simultaneously control the same resource or be in their critical section).
  2. Hold and Wait- processes currently holding resources can request new resources.
  3. No preemption- Once a process holds a resource, it cannot be taken away by another process or the kernel.
  4. Circular wait- Each process is waiting to obtain a resource which is held by another process.
  1. 互斥- 每个资源当前要么分配给一个进程,要么可用。(两个进程不能同时控制同一个资源或处于它们的临界区)。
  2. 保持和等待- 当前持有资源的进程可以请求新资源。
  3. 无抢占- 一旦一个进程持有一个资源,它就不能被另一个进程或内核夺走。
  4. 循环等待- 每个进程都在等待获取另一个进程持有的资源。

and all these condition are satisfied in above diagram.

并且所有这些条件都在上图中得到满足。

回答by 17 of 26

A deadlock happens when a thread is waiting for something that never occurs.

当线程正在等待从未发生过的事情时,就会发生死锁。

Typically, it happens when a thread is waiting on a mutex or semaphore that was never released by the previous owner.

通常,当线程正在等待前一个所有者从未释放过的互斥锁或信号量时,就会发生这种情况。

It also frequently happens when you have a situation involving two threads and two locks like this:

当您遇到涉及两个线程和两个锁的情况时,它也经常发生,如下所示:

Thread 1               Thread 2

Lock1->Lock();         Lock2->Lock();
WaitForLock2();        WaitForLock1();   <-- Oops!

You generally detect them because things that you expect to happen never do, or the application hangs entirely.

您通常会检测到它们,因为您期望发生的事情永远不会发生,或者应用程序完全挂起。

回答by onmyway133

You can take a look at this wonderful articles, under section Deadlock. It is in C# but the idea is still the same for other platform. I quote here for easy reading

您可以在Deadlock部分下查看这篇精彩文章。它是在 C# 中,但对于其他平台,这个想法仍然相同。我在这里引用以方便阅读

A deadlock happens when two threads each wait for a resource held by the other, so neither can proceed. The easiest way to illustrate this is with two locks:

当两个线程各自等待另一个线程持有的资源时,就会发生死锁,因此两者都无法继续。说明这一点的最简单方法是使用两个锁:

object locker1 = new object();
object locker2 = new object();

new Thread (() => {
                    lock (locker1)
                    {
                      Thread.Sleep (1000);
                      lock (locker2);      // Deadlock
                    }
                  }).Start();
lock (locker2)
{
  Thread.Sleep (1000);
  lock (locker1);                          // Deadlock
}

回答by Rohit Singh

Deadlock is a common problem in multiprocessing/multiprogramming problems in OS. Say there are two processes P1, P2 and two globally shareable resource R1, R2 and in critical section both resources need to be accessed

死锁是操作系统多处理/多道程序问题中的常见问题。假设有两个进程 P1、P2 和两个全局共享资源 R1、R2,并且在临界区,这两个资源都需要访问

Initially, the OS assigns R1 to process P1 and R2 to process P2. As both processes are running concurrently they may start executing their code but the PROBLEM arises when a process hits the critical section. So process R1 will wait for process P2 to release R2 and vice versa... So they will wait for forever (DEADLOCK CONDITION).

最初,操作系统将 R1 分配给进程 P1,将 R2 分配给进程 P2。由于两个进程同时运行,它们可能会开始执行它们的代码,但是当进程到达临界区时就会出现问题。所以进程 R1 将等待进程 P2 释放 R2,反之亦然......所以他们将永远等待(死锁条件)。

A small ANALOGY...

一个小类比...

Your Mother(OS),
You(P1),
Your brother(P2),
Apple(R1),
Knife(R2),
critical section(cutting apple with knife).

Your mother gives you the apple and the knife to your brother in the beginning.
Both are happy and playing(Executing their codes).
Anyone of you wants to cut the apple(critical section) at some point.
You don't want to give the apple to your brother.
Your brother doesn't want to give the knife to you.
So both of you are going to wait for a long very long time :)

你的母亲(OS),
你(P1),
你的兄弟(P2),
苹果(R1),
刀(R2),
临界区(用刀切苹果)。

一开始你妈妈把苹果和刀给了你弟弟。
两个人都很开心和玩耍(执行他们的代码)。
你们中的任何人都想在某个时候切开苹果(临界区)。
你不想把苹果给你弟弟。
你哥哥不想把刀给你。
所以你们俩都要等很久很久:)

回答by user207421

A deadlock occurs when there is a circular chain of threads or processes which each hold a locked resource and are trying to lock a resource held by the next element in the chain. For example, two threads that hold respectively lock A and lock B, and are both trying to acquire the other lock.

当存在一个线程或进程的循环链,每个线程或进程都持有一个锁定的资源并试图锁定链中下一个元素持有的资源时,就会发生死锁。例如,两个线程分别持有锁 A 和锁 B,并且都试图获取另一个锁。

回答by Joseph Sturtevant

Deadlock occurs when two threads aquire locks which prevent either of them from progressing. The best way to avoid them is with careful development. Many embedded systems protect against them by using a watchdog timer (a timer which resets the system whenever if it hangs for a certain period of time).

当两个线程获取阻止其中任何一个进程的锁时,就会发生死锁。避免它们的最好方法是仔细开发。许多嵌入式系统通过使用看门狗定时器(一种在系统挂起一段时间后重置系统的定时器)来防止它们。

回答by Vivek Pratap Singh

A classic and very simple program for understanding Deadlocksituation :-

用于理解死锁情况的经典且非常简单的程序:-

public class Lazy {

    private static boolean initialized = false;

    static {
        Thread t = new Thread(new Runnable() {
            public void run() {
                initialized = true;
            }
        });

        t.start();

        try {
            t.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        System.out.println(initialized);
    }
}

When the main thread invokes Lazy.main, it checks whether the class Lazy has been initialized and begins to initialize the class. The main thread now sets initialized to false , creates and starts a background thread whose run method sets initialized to true , and waits for the background thread to complete.

当主线程调用 Lazy.main 时,它会检查 Lazy 类是否已经初始化并开始初始化该类。主线程现在将 initialized 设置为 false ,创建并启动一个后台线程,其 run 方法将 initialized 设置为 true ,并等待后台线程完成。

This time, the class is currently being initialized by another thread. Under these circumstances, the current thread, which is the background thread, waits on the Class object until initialization is complete. Unfortunately, the thread that is doing the initialization, the main thread, is waiting for the background thread to complete. Because the two threads are now waiting for each other, the program is DEADLOCKED.

这一次,该类当前正在被另一个线程初始化。在这些情况下,当前线程,即后台线程,会等待 Class 对象,直到初始化完成。不幸的是,正在执行初始化的线程,即主线程,正在等待后台线程完成。因为这两个线程现在正在互相等待,所以程序处于DEADLOCKED。