Why go channel blocking

func TestPc(t *testing.T)  {
	wg := &sync.WaitGroup{}
	c := make(chan int)
	count1 := 0
	count2 := 0
	wg.Add(1)
	go Producter(c,wg,1,40)
	wg.Add(1)
	go Consumer(c,wg,"c1",count1)
	wg.Add(1)
	go Consumer(c,wg,"c2",count2)
	wg.Wait()
}

func Producter(ch chan int,wg *sync.WaitGroup,page int,size int)  {
	defer func() {    //匿名函数捕获错误
		err := recover()
		if err != nil {
			fmt.Println("add ele fail")
		}
	}()
	for i := page;i<size;i++{
		for j :=0;j<1000;j++{
			fmt.Println("pro",j+i)
			ch <- (i-1)*1000+j
		}
	}
	if size == 20 {
		fmt.Println("producter ok")
		wg.Done()
		close(ch)
	}
}

func Consumer(ch chan int,wg *sync.WaitGroup,name string,count int)  {
	count++
	defer func() {    //匿名函数捕获错误
		err := recover()
		if err != nil {
			fmt.Println("ch ele fail")
		}
	}()
	doc := <- ch
	fmt.Println("ch-"+name,doc)
	if count==20000{
		fmt.Println("ch-",name,"done")
		wg.Done()
	}
}

just output:
=== RUN TestPc
pro 1
ch-c1 0
pro 2
ch-c2 1
pro 3

3 Likes

thank you i will try it

1 Like

Can you help me solve my problem?

1 Like

What do you expect to happen?

1 Like

i want the consumer goroutine print all the product number

1 Like

Hi @yinde_cui,

You currently have 2 consumers that are only receiving off a channel one time, where your producer is placing on a channel many times.

If you only want 2 consumer goroutines, each of them should constantly try to accept a value from the channel. Here is an updated example from your code.

Please see notes in the code.

https://play.golang.org/p/ejBCVr2IZ09

2 Likes

thank you first,can you put your code on the reply,
i can not open your link
Viewing and/or sharing code snippets is not available in your country for legal reasons. This message might also appear if your country is misdetected. If you believe this is an error, please file an issue.

1 Like
package main

import (
	"fmt"
	"sync"
)

func main() {
	wg := &sync.WaitGroup{}
	c := make(chan int)
	count1 := 0
	count2 := 0
	wg.Add(1)
	go Producter(c, wg, 1, 40)
	wg.Add(1)
	go Consumer(c, wg, "c1", count1)
	wg.Add(1)
	go Consumer(c, wg, "c2", count2)
	wg.Wait()
}

func Producter(ch chan int, wg *sync.WaitGroup, page int, size int) {
	defer func() {
		err := recover()
		if err != nil {
			fmt.Println("add ele fail")
		}
	}()
	for i := page; i < size; i++ {
		for j := 0; j < 1000; j++ {
			fmt.Println("pro", j+i)
			ch <- (i-1)*1000 + j
		}
	}
	if size == 20 {
		fmt.Println("producter ok")
	}

	// NOTE: Done needs to be called even if size is not 20.
	wg.Done()
	close(ch)
}

func Consumer(ch chan int, wg *sync.WaitGroup, name string, count int) {
	defer func() { //匿名函数捕获错误
		err := recover()
		if err != nil {
			fmt.Println("ch ele fail")
		}
	}()

	// NOTE: You want to actually loop through the channel.
	for doc := range ch {
		count++

		fmt.Println("ch-"+name, doc)
		if count == 20000 {
			fmt.Println("ch-", name, "done")
		}
	}

	wg.Done()
}
1 Like

i got it ,thank you very very much:smiley:

2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.