Why is this a dead end in golang / waitgroup?

I'm not sure what I am missing, but I have a dead end error. I use the buffer channel, which I use after completing all the procedures. The channel has a capacity of 4, and I start 4 procedures, so I expect it to be "closed" automatically as soon as it reaches its maximum capacity.

package main

import "fmt"
import "sync"

func main() {
    ch := make(chan []int, 4)
    var m []int

    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            ch <- m
            return
        }()
    }
    wg.Wait()

    for c := range ch {
        fmt.Printf("c is %v", c)
    }
}
+5
source share
3 answers

You have two problems:

  • There is not enough space for all goroutines, since your channel is too small: when your channel is full, the remaining goroutines must wait for the slot to free.
  • range ch still waiting for the elements to appear in the channel, and goroutine will not remain on it.

Solution 1:

Make the channel large enough and close it so that it rangestops waiting:

ch := make(chan []int, 5)
...
wg.Wait()
close(ch)

Demonstration

, , , .

2: , ( ), Done() :

func main() {
    ch := make(chan []int, 4)
    var m []int

    var wg sync.WaitGroup
    for i := 0; i < 5; i++ {
        wg.Add(1)
        go func() {
            ch <- m
            return
        }()
    }
    go func() {
        for c := range ch {
            fmt.Printf("c is %v\n", c)
            wg.Done()
        }
    }()
    wg.Wait()
}

+9

4 go

, 5 - , , 4 .

, . , , 5 .

,

ch := make(chan []int, 5)

close(ch) 

range.

+8

you can try to run this code without wg and is still at a dead end; What for? Just because the main procedure is blocked by ch, so the program is paused and timed out, and you get a deadlock error. The main reason is that ch blocks the main mode.

func main() {
    ch := make(chan []int, 4) // No matter which int number 
    var m []int
    for i := 0; i < 5; i++ {
        go func() {
            ch <- m
            return
        }()
    }
    for c := range ch {
        fmt.Printf("c is %v \n", c)
    }
}
0
source

Source: https://habr.com/ru/post/1547396/


All Articles