temporarya
temporarya

Reputation: 755

Do we need to create new waitgroups after it's done waiting?

I am facing a bit of a concurrency issue. I am writing a concurrent application for the first time.

What I am trying to achieve

Dependent functions ( using goroutines ) i.e. func2 is dependent on the result of func1

Problem

If I reuse the waitgroup after it's done waiting I get an error as

fatal error: all goroutines are asleep - deadlock!

Here's my code ( Playground ) :

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    wg := sync.WaitGroup{}
    ch := make(chan int)
    for a := 0; a < 3; a++ {
        wg.Add(1)
        go func1(int(3-a), ch, &wg)
    }
    go func() {
        wg.Wait()
        close(ch)
    }()
    //wg2 := sync.WaitGroup{} //<-- If I uncomment this and the corresponding wg2 code, then the snippet runs fine
    ch2 := make(chan string)
    for val := range ch {
        fmt.Println(val)
        wg.Add(1)
        //wg2.Add(1)
        go func2(val, ch2, &wg)
        //go func2(val, ch2, &wg2)
    }
    go func() {
        wg.Wait()
        //wg2.Wait()
        close(ch2)
    }()
    for val := range ch2 {
        fmt.Println(val)
    }
}

func func1(seconds int, ch chan<- int, wg *sync.WaitGroup) {
    defer wg.Done()
    time.Sleep(time.Duration(seconds) * time.Second)
    ch <- seconds
}

func func2(seconds int, ch chan<- string, wg *sync.WaitGroup) {
    defer wg.Done()
    ch <- "hello"
}


So, you can see, if I create a new WaitGroup it works fine else deadlock arises.

Thanks
Temporarya
( A golang noobie )

Upvotes: 0

Views: 689

Answers (1)

Eli Bendersky
Eli Bendersky

Reputation: 273416

WaitGroups can be safely reused but it's not clear why you're using a third-party package for this? Especially if you're just learning concurrency, I would strongly recommend you to stick to the standard library - sync.WaitGroup is what you need.

FWIW, if I modify your code to use sync.WaitGroup, it doesn't deadlock and runs to completion - see this playground

This Go blog post explains how to do pipelining safely with channels, and in some more advanced cases wait groups (you don't always need them)

Upvotes: 2

Related Questions