Deadlock in asynchronous traps: the death of asynchronous traps

Source: Internet
Author: User

Deadlock in asynchronous traps: the death of asynchronous traps

Asynchronous programming is promoted to give users a better front-end experience, but asynchronous programming also greatly increases the learning cost and the chance of making mistakes. The most common and difficult to handle is deadlock.

What is a "Deadlock"? The term "Deadlock". When two or more computing units are waiting for the other side to stop running to obtain system resources, but no one exits early, this situation is called a deadlock.

For example, here is a typical deadlock sample code:

int sharedResource1 = 1, sharedResource2 = 2;var lockResource1 = newobject();var lockResource2 = newobject();var t1 = newThread(() =>{    Console.WriteLine("thead 1 begin");    lock (lockResource1)    {        Thread.Sleep(10);        lock (lockResource2)        {            sharedResource1++;            sharedResource2++;        }    }    Console.WriteLine("thead 1 end");});var t2 = newThread(() =>{    Console.WriteLine("thead 2 begin");    lock (lockResource2)    {        Thread.Sleep(10);        lock (lockResource1)        {            sharedResource1++;            sharedResource2++;        }    }    Console.WriteLine("thead 2 end");});t1.Start();t2.Start();

The running result is as follows, and "thread x end" is never displayed ":

This is a deadlock caused by locking requests in different order, thanks to the detailed explanations of such deadlocks in our textbooks. I have mentioned this here, next, let's take a look at some of the more specific deadlocks often encountered in daily development-thread deadlocks.

Scenario 1: Waiting between tasks leads to a deadlock:

Task t1 = null, t2 = null;t1 = Task.Factory.StartNew(() =>{    Console.WriteLine("task 1 begin");    Task.Delay(10);    Task.WaitAll(t2);    Console.WriteLine("task 1 end");});t2 = Task.Factory.StartNew(() =>{    Console.WriteLine("task 2 begin");    Task.Delay(10);    Task.WaitAll(t1);    Console.WriteLine("task 2 end");});Task.WaitAll(t1, t2);Console.WriteLine("Done");

Scenario 2-winform Invoke grabs the UI thread deadlock:

privatevoid button1_Click(object sender, EventArgs e){    var t = Task.Factory.StartNew<string>(() =>        {            Thread.Sleep(0);            var text = Invoke(newFunc<string>(() =>            {                // do some ui-dependent works                return Text;            }));            return text + " - new title";        });    Text = t.Result;}

Scenario 3-WPF Dispatcher failover deadlock

privatevoid Button_Click(object sender, RoutedEventArgs e){    var t = Task.Factory.StartNew<Brush>((state) =>    {        Task.Delay(10);        var clr = (Color)newColorConverter()            .ConvertFromInvariantString(state asstring);        var brush = Dispatcher.Invoke<SolidColorBrush>(() =>            {                // do some works                returnnewSolidColorBrush() { Color = clr };            });        return brush;    }, "red");    theButton.Background = t.Result;}

Here we will streamline the screening of various irrelevant code, and we will soon be able to find problems in these situations. Yes, in fact, the above scenarios are all the same reason-wait thread lock: after the main execution thread calls the sub-thread, it suspends and waits for the sub-thread results. The sub-thread needs to switch to the main thread or wait for the return of the main thread, causing both threads to be in a blocking status (deadlock ), as shown in:


The solution is simple. Remove all synchronization waits. at least ensure that synchronization waits are not used on the main thread. How can this problem be solved? You can choose a variety of options. Here I would like to introduce some ideas and solutions.

1. Remove all wait services and rewrite them with the async and await keywords. We recommend that you use them.
Here you may be confused. Why can async and await ensure that thread deadlocks are not involved? As shown in the code snippet, after the current thread executes (1), it then executes (2). Note that the execution here (2) will switch the thread, but it is not blocking the current thread ,. NET has played a "trick" here. The actual compiler will automatically insert some code when it finds the async and await keywords, and use the state machine to mark the position in (3, let the current thread "fly" for a while, wait until the sub-thread in which await is located ends, modify the state machine status, and restore the current thread to (3) Here, then we can run (4). From the developer's perspective, it seems that this piece of code is executed in sequence. It is important that there is no wait lock here.

2. Remove all wait and use Task. ContinueWith to implement code sequence.
Var ta = new Task () =>{ doSome ();});
Ta. ContinueWith (tc) =>{ doAnother (tc. Result );});

3. Remove all wait, move the code after wait to a separate call, and activate the main thread at the end of the subthread by using the event or callback function. Take WinForm as an example, as shown in:

The Code project for testing mentioned in the article is attached:


In Java, is a deadlock caused by synchronization or Asynchronization?

A deadlock occurs.

The three threads A, B, and C both hold one resource and request another resource occupied by others. The situation of multiple participants is similar, it is a process like what we usually say that one hand pays and one hand delivers the goods, but both parties do not let go.

Therefore, A deadlock occurs only when at least two participants are involved at the same time. synchronization is performed first, and synchronization is performed later. The deadlock will not occur because when A is not finished, B is not started to run, therefore, B cannot compete for the resources required by.

In Java, is a deadlock caused by synchronization or Asynchronization?

Standard answer! A deadlock occurs. The three threads A, B, and C both hold one resource and request another resource occupied by others. The situation of multiple participants is similar, it is a process like what we usually say that one hand pays and one hand delivers the goods, but both parties do not let go. Therefore, A deadlock occurs only when at least two participants are involved at the same time. synchronization is performed first, and synchronization is performed later. The deadlock will not occur because when A is not finished, B is not started to run, therefore, B cannot compete for the resources required by.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.