Golang中为什么会出现channel阻塞问题

Golang中为什么会出现channel阻塞问题

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()
	}
}

仅输出: === RUN TestPc pro 1 ch-c1 0 pro 2 ch-c2 1 pro 3


更多关于Golang中为什么会出现channel阻塞问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

8 回复

感谢,我会尝试一下

更多关于Golang中为什么会出现channel阻塞问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你期望发生什么?

你能帮我解决我的问题吗?

我明白了,非常感谢你:笑脸:

我希望消费者协程能打印所有的产品编号

首先感谢你,能否在回复中贴出你的代码, 我无法打开你的链接 由于法律原因,您所在的国家/地区无法查看和/或共享代码片段。如果您的国家/地区被误检测,也可能显示此消息。如果您认为这是一个错误,请提交问题

你好,

你目前有两个消费者,它们各自只从通道接收一次数据,而你的生产者却在向通道发送多次数据。

如果你只需要两个消费者协程,那么它们每个都应该持续尝试从通道接收值。以下是根据你的代码更新的示例。

请查看代码中的注释。

func main() {
    // 示例代码
}
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")
	}

	// 注意:即使大小不等于20,也需要调用Done方法。
	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")
		}
	}()

	// 注意:您需要实际遍历通道。
	for doc := range ch {
		count++

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

	wg.Done()
}
回到顶部