Explain in detail the common deadlock situations in golang concurrent operations

Time:2021-9-27

What is a deadlock? In the go process, a deadlock is usually permanently blocked. You take my things and ask me to give them to you first and then to me. I take your things and ask you to give them to me first, otherwise I won’t give them to you. If we both think so, it won’t be solved.

The first case: the pipeline without cache capacity writes and reads by itself

First code:

?
1
2
3
4
5
6
7
func main() {
    ch := make(chan int, 0)
    ch <- 666
    x := <- ch
    fmt.Println(x)
}

We can see that this is a pipeline without cache capacity, and then write 666 to it, and then read it in the pipeline. There must be a problem! A pipeline without cache capacity, no one can read, you can’t write, no one can write, you can’t read, this is a deadlock!

fatal error: all goroutines are asleep – deadlock!

The solution is very simple. Open up two collaborative processes, one for writing and one for reading.

The second situation: the cooperation process is late

?
1
2
3
4
5
6
7
func main() {
    ch := make(chan int,0)
    ch <- 666
    go func() {
        <- ch
    }()
}

We can see that after the number is written to the pipeline, the pipeline cannot write because no one reads it, and then the operation of writing to the pipeline is blocked all the time. At this time, you have doubts. Didn’t you open up a cooperative process to read? However, after the process is written to the pipeline, if it cannot be written to the pipeline, the process cannot be opened.

The third situation: when the pipeline reads and writes, they ask each other to read / write first

If you ask each other to read / write first and then read / write by yourself, it will cause deadlock.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func main() {
    chHusband := make(chan int,0)
    chWife := make(chan int,0)
    go func() {
        select {
        case <- chHusband:
            chWife<-888
        }
    }()
    select {
        case <- chWife:
            chHusband <- 888
    }
}

Let’s take a look at his wife Xiecheng first. Chwife will give her husband a big red envelope of 888 as long as she can read it, that is, her wife has money.

Look at my husband’s cooperation process. It’s amazing. What’s the matter? The husband also said that as long as he had money, he would give his wife a big red envelope of 888.

Both said they had no money, the husband couldn’t send a red envelope to his wife, and the wife couldn’t send a red envelope to her husband. This is a deadlock!

The fourth case: read and write locks block each other, forming an invisible deadlock

Let’s take a look at the code:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func main() {
    var rmw09 sync.RWMutex
    ch := make(chan int,0)
    go func() {
        rmw09.Lock()
        ch <- 123
        rmw09.Unlock()
    }()
    go func() {
        rmw09.RLock()
        x := <- ch
        FMT. Println ("read", x)
        rmw09.RUnlock()
    }()
    for {
        runtime.GC()
    }
}

For these two processes, if the first process grabs the write only lock first, and the other process cannot grab the read-only lock, then the first process cannot write because the other process does not read.

If the second orchestration grabs the read-only lock first, the other orchestration cannot grab the write only lock. Then, because the other orchestration is not written, the second orchestration cannot be read.

This is the end of this article about explaining the common deadlock situations in golang concurrent operations. For more information about golang concurrent deadlock, please search the previous articles of developeppaper or continue to browse the relevant articles below. I hope you will support developeppaper in the future!

Recommended Today

Seven Python code review tools recommended

althoughPythonLanguage is one of the most flexible development languages at present, but developers often abuse its flexibility and even violate relevant standards. So PythoncodeThe following common quality problems often occur: Some unused modules have been imported Function is missing arguments in various calls The appropriate format indentation is missing Missing appropriate spaces before and after […]