How to Prevent Deadlock in Golang When Using Goroutines and Channels?

Susan Sarandon
Release: 2024-10-27 06:48:29
Original
403 people have browsed it

How to Prevent Deadlock in Golang When Using Goroutines and Channels?

Solving Goroutines Deadlock

When working with concurrent Golang programs, you may encounter a deadlock error: "fatal error: all goroutines are asleep - deadlock!". This error occurs when multiple goroutines are waiting on each other to perform a task, creating a deadlock situation.

Consider the following code:

<code class="go">func producer(ch chan int, d time.Duration, num int) {
    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    ch := make(chan int)

    go producer(ch, 100*time.Millisecond, 2)
    go producer(ch, 200*time.Millisecond, 5)

    for {
        fmt.Println(<-ch)    
    }

    close(ch)
}</code>
Copy after login

This code creates two producer goroutines that send values to the same channel. The main goroutine continuously receives values from the channel in an endless loop.

The problem arises because the producers are "short-lived" and stop sending values after a finite amount of time, but the main goroutine continues receiving values endlessly. This creates a deadlock since the channel is never closed to signal that no more values will be sent.

To solve this deadlock, we must ensure that the channel is closed when all producers have completed their tasks. The efficient way to achieve this is to use a synchronization primitive like a sync.WaitGroup.

Here's a modified version of the code:

<code class="go">func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) {
    defer wg.Done()

    for i := 0; i < num; i++ {
        ch <- i
        time.Sleep(d)
    }
}

func main() {
    wg := &sync.WaitGroup{}
    ch := make(chan int)

    wg.Add(1)
    go producer(ch, 100*time.Millisecond, 2, wg)
    wg.Add(1)
    go producer(ch, 200*time.Millisecond, 5, wg)

    go func() {
        wg.Wait()
        close(ch)
    }()

    for v := range ch {
        fmt.Println(v)
    }
}</code>
Copy after login

In this code, we pass a sync.WaitGroup to each producer goroutine. Each producer increments the waitgroup before starting and decrements it when it finishes. The main goroutine waits for the completion of all producers using wg.Wait(). Once all producers have finished, the main goroutine closes the channel.

This solution ensures that the channel is only closed after all producers have completed their work, preventing a deadlock situation.

The above is the detailed content of How to Prevent Deadlock in Golang When Using Goroutines and Channels?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!