You might want to consider using a sync.WaitGroup. It’s for such situations.
John John Souvestre - New Orleans LA From: golang-nuts@googlegroups.com [mailto:golang-nuts@googlegroups.com] On Behalf Of bill.war...@talentinc.com Sent: 2017 August 18, Fri 13:01 To: golang-nuts Subject: [go-nuts] Is this bad concurrency? Hi, https://play.golang.org/p/lR6_mxSjtb I have two long running things to do, I'd like to do them in parallel, then sync up at the end. I've written it as a function which gets one thing done, and which backgrounds the second thing with a goroutine. Thing one has a lot of reasons to exit early, and I need to signal those to thing two so that the go routine can exit cleanly and not create a goroutine leak. Standard fare, usually solved by introducing a channel and a select statement. I want to signal done for early exits, including panics, so I thought I would write to the done channel in a defer block. That caused a problem, because in the happy case, both the foreground and the background routines are finished, the done channel has no reader, so writing to it in the defer block causes "fatal error: all goroutines are asleep - deadlock!" So I introduced a new boolean variable ("clean_finish") that is false until the background job completes, and which is tested in the defer block before writing to the done channel. Is there anything wrong with my approach? You can see the code in the playground link above, or down below. package main import ( "sync/atomic" "fmt" "time" ) func main() { ch := make(chan int) done := make(chan struct{}) var clean_finish uint32 defer func() { fin := atomic.LoadUint32(&clean_finish) if fin != 1 { done <- struct{}{} } }() go func() { defer func() { fmt.Println("we're done here") }() select { case <-time.After(time.Second * 1): ch <- 1 atomic.StoreUint32(&clean_finish, 1) case <- done: fmt.Println("early exit") } }() panic("bye") // comment this out to see normal behavior n := <- ch fmt.Printf("n: %v\n", n) } -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.