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 回复
你期望发生什么?
你能帮我解决我的问题吗?
我明白了,非常感谢你:笑脸:
我希望消费者协程能打印所有的产品编号
首先感谢你,能否在回复中贴出你的代码, 我无法打开你的链接 由于法律原因,您所在的国家/地区无法查看和/或共享代码片段。如果您的国家/地区被误检测,也可能显示此消息。如果您认为这是一个错误,请提交问题。
你好,
你目前有两个消费者,它们各自只从通道接收一次数据,而你的生产者却在向通道发送多次数据。
如果你只需要两个消费者协程,那么它们每个都应该持续尝试从通道接收值。以下是根据你的代码更新的示例。
请查看代码中的注释。
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()
}

