衡阳网站建设icp备,网站英文域名,定制软件开发软件,简约ins风工作室名字本文翻译自#xff1a;Whats the difference between deadlock and livelock?
有人可以举例说明#xff08;代码#xff09; 死锁和活锁有什么区别吗#xff1f; #1楼
参考#xff1a;https://stackoom.com/question/PpRX/死锁和活锁有什么区别 #2楼 Livelock 活锁 A…本文翻译自Whats the difference between deadlock and livelock?
有人可以举例说明代码 死锁和活锁有什么区别吗 #1楼
参考https://stackoom.com/question/PpRX/死锁和活锁有什么区别 #2楼 Livelock 活锁 A thread often acts in response to the action of another thread. 一个线程通常会响应另一个线程的操作而行动。 If the other threads action is also a response to the action of another thread, then livelock may result. 如果另一个线程的动作也是对另一个线程的动作的响应则可能会导致活锁。 As with deadlock, livelocked threads are unable to make further progress . 与死锁一样活锁的线程无法继续前进 。 However, the threads are not blocked — they are simply too busy responding to each other to resume work . 但是 线程没有被阻塞 -它们只是太忙于彼此响应而无法恢复工作 。 This is comparable to two people attempting to pass each other in a corridor: Alphonse moves to his left to let Gaston pass, while Gaston moves to his right to let Alphonse pass. 这相当于两个人试图在走廊中互相经过阿方斯Alphonse向左移动以让加斯顿Gaston通过而格斯顿Gaston向右移动以让Alphonse通过。 Seeing that they are still blocking each other, Alphonse moves to his right, while Gaston moves to his left. 看到他们仍然互相阻挡阿方斯Alphonse向右移动而加斯顿Gaston向左移动。 Theyre still blocking each other, and so on... 他们仍然互相阻碍依此类推... The main difference between livelock and deadlock is that threads are not going to be blocked, instead they will try to respond to each other continuously. 活锁和死锁之间的主要区别在于线程不会被阻塞而是会尝试不断地相互响应。 In this image, both circles (threads or processes) will try to give space to the other by moving left and right. 在此图像中两个圆圈线程或进程都将尝试通过左右移动来给另一个空间。 But they cant move any further. 但是他们不能继续前进。 #3楼 All the content and examples here are from 这里的所有内容和示例均来自 Operating Systems: Internals and Design Principles 操作系统内部和设计原则 William Stallings 威廉·斯托林斯 8º Edition 8º版 Deadlock : A situation in which two or more processes are unable to proceed because each is waiting for one the others to do something. 死锁 一种情况其中两个或多个进程无法进行因为每个进程都在等待另一个进程在做某事。 For example, consider two processes, P1 and P2, and two resources, R1 and R2. 例如考虑两个进程P1和P2以及两个资源R1和R2。 Suppose that each process needs access to both resources to perform part of its function. 假设每个进程都需要访问两个资源才能执行其部分功能。 Then it is possible to have the following situation: the OS assigns R1 to P2, and R2 to P1. 然后可能出现以下情况OS将R1分配给P2将R2分配给P1。 Each process is waiting for one of the two resources. 每个进程都在等待两种资源之一。 Neither will release the resource that it already owns until it has acquired the other resource and performed the function requiring both resources. 在获得另一资源并执行需要这两种资源的功能之前它们都不会释放它已经拥有的资源。 The two processes are deadlocked 这两个过程陷入僵局 Livelock : A situation in which two or more processes continuously change their states in response to changes in the other process(es) without doing any useful work: 活锁 两个或多个进程在不做任何有用工作的情况下不断响应其他进程的更改而更改其状态的情况 Starvation : A situation in which a runnable process is overlooked indefinitely by the scheduler; 饥饿 调度程序无限期地忽略可运行进程的情况 although it is able to proceed, it is never chosen. 尽管它能够继续进行但从未选择。 Suppose that three processes (P1, P2, P3) each require periodic access to resource R. Consider the situation in which P1 is in possession of the resource, and both P2 and P3 are delayed, waiting for that resource. 假设三个进程P1P2P3每个都需要定期访问资源R。请考虑以下情况P1拥有该资源并且P2和P3都被延迟等待该资源。 When P1 exits its critical section, either P2 or P3 should be allowed access to R. Assume that the OS grants access to P3 and that P1 again requires access before P3 completes its critical section. 当P1退出其关键部分时应该允许P2或P3访问R。假定OS授予对P3的访问权限并且P1在P3完成其关键部分之前再次需要访问。 If the OS grants access to P1 after P3 has finished, and subsequently alternately grants access to P1 and P3, then P2 may indefinitely be denied access to the resource, even though there is no deadlock situation. 如果OS在P3完成后授予对P1的访问权限然后又交替授予对P1和P3的访问权限那么即使没有死锁情况P2也可能无限期地被拒绝访问资源。 APPENDIX A - TOPICS IN CONCURRENCY 附录A-同步主题 Deadlock Example 死锁示例 If both processes set their flags to true before either has executed the while statement, then each will think that the other has entered its critical section, causing deadlock. 如果两个进程在执行一个while语句之前将它们的标志设置为true则每个进程将认为另一个进程已进入其临界区从而导致死锁。
/* PROCESS 0 */
flag[0] true;
while (flag[1]) /* do nothing */;
/* critical section*/;
flag[0] false; /* PROCESS 1 */
flag[1] true;
while (flag[0])/* do nothing */;
/* critical section*/;
flag[1] false;Livelock Example 活锁示例
/* PROCESS 0 */
flag[0] true;
while (flag[1]){flag[0] false; /*delay */;flag[0] true;
}
/*critical section*/;
flag[0] false; /* PROCESS 1 */
flag[1] true;
while (flag[0]) {flag[1] false;/*delay */;flag[1] true;
}
/* critical section*/;
flag[1] false;[...] consider the following sequence of events: [...]考虑以下事件顺序 P0 sets flag[0] to true. P0将标志[0]设置为true。 P1 sets flag[1] to true. P1将flag [1]设置为true。 P0 checks flag[1]. P0检查标志[1]。 P1 checks flag[0]. P1检查标志[0]。 P0 sets flag[0] to false. P0将标志[0]设置为false。 P1 sets flag[1] to false. P1将flag [1]设置为false。 P0 sets flag[0] to true. P0将标志[0]设置为true。 P1 sets flag[1] to true. P1将flag [1]设置为true。 This sequence could be extended indefinitely, and neither process could enter its critical section. 此序列可以无限期扩展并且任何过程都不能进入其关键部分。 Strictly speaking, this is not deadlock , because any alteration in the relative speed of the two processes will break this cycle and allow one to enter the critical section. 严格来说这不是死锁 因为这两个过程的相对速度的任何改变都将中断此循环并允许一个进入关键部分。 This condition is referred to as livelock . 这种情况称为活锁 。 Recall that deadlock occurs when a set of processes wishes to enter their critical sections but no process can succeed. 回想一下当一组进程希望进入其关键部分而没有成功的进程时就会发生死锁。 With livelock , there are possible sequences of executions that succeed, but it is also possible to describe one or more execution sequences in which no process ever enters its critical section. 使用livelock时 可能有成功的执行序列但是也可能描述一个或多个执行序列其中没有进程进入其关键部分。 #4楼 Maybe these two examples illustrate you the difference between a deadlock and a livelock: 也许这两个示例向您说明了死锁和活锁之间的区别 Java-Example for a deadlock: Java-死锁示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class DeadlockSample {private static final Lock lock1 new ReentrantLock(true);private static final Lock lock2 new ReentrantLock(true);public static void main(String[] args) {Thread threadA new Thread(DeadlockSample::doA,Thread A);Thread threadB new Thread(DeadlockSample::doB,Thread B);threadA.start();threadB.start();}public static void doA() {System.out.println(Thread.currentThread().getName() : waits for lock 1);lock1.lock();System.out.println(Thread.currentThread().getName() : holds lock 1);try {System.out.println(Thread.currentThread().getName() : waits for lock 2);lock2.lock();System.out.println(Thread.currentThread().getName() : holds lock 2);try {System.out.println(Thread.currentThread().getName() : critical section of doA());} finally {lock2.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 2 any longer);}} finally {lock1.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 1 any longer);}}public static void doB() {System.out.println(Thread.currentThread().getName() : waits for lock 2);lock2.lock();System.out.println(Thread.currentThread().getName() : holds lock 2);try {System.out.println(Thread.currentThread().getName() : waits for lock 1);lock1.lock();System.out.println(Thread.currentThread().getName() : holds lock 1);try {System.out.println(Thread.currentThread().getName() : critical section of doB());} finally {lock1.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 1 any longer);}} finally {lock2.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 2 any longer);}}
}Sample output: 样本输出
Thread A : waits for lock 1
Thread B : waits for lock 2
Thread A : holds lock 1
Thread B : holds lock 2
Thread B : waits for lock 1
Thread A : waits for lock 2Java-Example for a livelock: 活锁的Java示例
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LivelockSample {private static final Lock lock1 new ReentrantLock(true);private static final Lock lock2 new ReentrantLock(true);public static void main(String[] args) {Thread threadA new Thread(LivelockSample::doA, Thread A);Thread threadB new Thread(LivelockSample::doB, Thread B);threadA.start();threadB.start();}public static void doA() {try {while (!lock1.tryLock()) {System.out.println(Thread.currentThread().getName() : waits for lock 1);Thread.sleep(100);}System.out.println(Thread.currentThread().getName() : holds lock 1);try {while (!lock2.tryLock()) {System.out.println(Thread.currentThread().getName() : waits for lock 2);Thread.sleep(100);}System.out.println(Thread.currentThread().getName() : holds lock 2);try {System.out.println(Thread.currentThread().getName() : critical section of doA());} finally {lock2.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 2 any longer);}} finally {lock1.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 1 any longer);}} catch (InterruptedException e) {// can be ignored here for this sample}}public static void doB() {try {while (!lock2.tryLock()) {System.out.println(Thread.currentThread().getName() : waits for lock 2);Thread.sleep(100);}System.out.println(Thread.currentThread().getName() : holds lock 2);try {while (!lock1.tryLock()) {System.out.println(Thread.currentThread().getName() : waits for lock 1);Thread.sleep(100);}System.out.println(Thread.currentThread().getName() : holds lock 1);try {System.out.println(Thread.currentThread().getName() : critical section of doB());} finally {lock1.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 1 any longer);}} finally {lock2.unlock();System.out.println(Thread.currentThread().getName() : does not hold lock 2 any longer);}} catch (InterruptedException e) {// can be ignored here for this sample}}
}Sample output: 样本输出
Thread B : holds lock 2
Thread A : holds lock 1
Thread A : waits for lock 2
Thread B : waits for lock 1
Thread B : waits for lock 1
Thread A : waits for lock 2
Thread A : waits for lock 2
Thread B : waits for lock 1
Thread B : waits for lock 1
Thread A : waits for lock 2
Thread A : waits for lock 2
Thread B : waits for lock 1
...Both examples force the threads to aquire the locks in different orders. 这两个示例都强制线程以不同的顺序获取锁。 While the deadlock waits for the other lock, the livelock does not really wait - it desperately tries to acquire the lock without the chance of getting it. 当死锁等待另一个锁时活锁并没有真正等待-它拼命尝试获取该锁而没有机会获得它。 Every try consumes CPU cycles. 每次尝试都会消耗CPU周期。 #5楼 Imagine youve thread A and thread B. They are both synchronised on the same object and inside this block theres a global variable they are both updating; 假设您有线程A和线程B。它们都在同一个对象上synchronised 并且在此块中有一个全局变量它们都在更新
static boolean commonVar false;
Object lock new Object;...void threadAMethod(){...while(commonVar false){synchornized(lock){...commonVar true}}
}void threadBMethod(){...while(commonVar true){synchornized(lock){...commonVar false}}
}So, when thread A enters in the while loop and holds the lock, it does what it has to do and set the commonVar to true . 因此当线程A进入while循环并持有锁时它将执行它必须执行的操作并将commonVar设置为true 。 Then thread B comes in, enters in the while loop and since commonVar is true now, it is be able to hold the lock. 然后线程B进入进入while循环由于commonVar现在为true 因此它能够持有该锁。 It does so, executes the synchronised block, and sets commonVar back to false . 这样做执行synchronised块并将commonVar设置回false 。 Now, thread A again gets its new CPU window, it was about to quit the while loop but thread B has just set it back to false , so the cycle repeats over again. 现在再次线程A得到它的新的CPU窗口它是要退出while循环但线程B刚刚设置回false 如此循环再次重复了。 Threads do something (so theyre not blocked in the traditional sense) but for pretty much nothing. 线程可以执行某些操作因此在传统意义上不会被阻塞但几乎没有任何作用。 It maybe also nice to mention that livelock does not necessarily have to appear here. 可能还需要提及的是活锁不一定必须出现在此处。 Im assuming that the scheduler favours the other thread once the synchronised block finish executing. 我假设一旦synchronised块完成执行调度程序就会偏向另一个线程。 Most of the time, I think its a hard-to-hit expectation and depends on many things happening under the hood. 在大多数时候我认为这是一个很难达到的期望它取决于引擎盖下发生的许多事情。 #6楼 Taken from http://en.wikipedia.org/wiki/Deadlock : 取自http://en.wikipedia.org/wiki/Deadlock In concurrent computing, a deadlock is a state in which each member of a group of actions, is waiting for some other member to release a lock 在并发计算中 死锁是一种状态其中一组动作中的每个成员都在等待其他成员释放锁 A livelock is similar to a deadlock, except that the states of the processes involved in the livelock constantly change with regard to one another, none progressing. 活锁类似于死锁不同之处在于活锁中涉及的进程的状态彼此之间不断变化没有进展。 Livelock is a special case of resource starvation; Livelock是资源匮乏的特例 the general definition only states that a specific process is not progressing. 一般定义仅指出特定过程没有进展。 A real-world example of livelock occurs when two people meet in a narrow corridor, and each tries to be polite by moving aside to let the other pass, but they end up swaying from side to side without making any progress because they both repeatedly move the same way at the same time. 当两个人在狭窄的走廊里相遇时发生了现实生活中的活锁例子每个人都试图通过移动到一边让对方经过而礼貌但最终却没有任何进展就左右摇摆因为他们都反复移动在同一时间相同的方式。 Livelock is a risk with some algorithms that detect and recover from deadlock. 对于某些检测死锁并从死锁中恢复的算法活锁是一种风险。 If more than one process takes action, the deadlock detection algorithm can be repeatedly triggered. 如果有多个进程采取措施则死锁检测算法可以重复触发。 This can be avoided by ensuring that only one process (chosen randomly or by priority) takes action. 通过确保只有一个过程随机选择或优先选择可以采取措施可以避免这种情况。