Go 不能处理一个常规的呆头呆脑的人
我试图广播一条消息到一个频道,我只希望它发送5条消息。但我总是犯这样的错误: 致命错误:所有goroutine都处于休眠状态-死锁 我的代码:Go 不能处理一个常规的呆头呆脑的人,go,broadcast,goroutine,Go,Broadcast,Goroutine,我试图广播一条消息到一个频道,我只希望它发送5条消息。但我总是犯这样的错误: 致命错误:所有goroutine都处于休眠状态-死锁 我的代码: package main import ( "log" "sync" broadcast "github.com/dustin/go-broadcast" "github.com/pwaller/barrier" ) //Message boradcasted type Message struct { y
package main
import (
"log"
"sync"
broadcast "github.com/dustin/go-broadcast"
"github.com/pwaller/barrier"
)
//Message boradcasted
type Message struct {
y string
x int
}
var w sync.WaitGroup
var bar barrier.Barrier
func main() {
b := broadcast.NewBroadcaster(100)
w.Add(1)
go workerOne(b)
d := Message{"message :", 0}
go func() {
for i := 0; i < 5; i++ {
d.x = i
log.Printf("Sending %v", d)
b.Submit(d)
}
<-bar.Barrier()
b.Close()
}()
w.Wait()
}
func workerOne(b broadcast.Broadcaster) {
ch := make(chan interface{})
b.Register(ch)
for {
v, ok := <-ch
if ok {
log.Printf("workerOne() reading : %v", v)
} else {
log.Printf("i am here")
close(ch)
b.Unregister(ch)
bar.Fall()
w.Done()
return
}
}
}
我什么都试过了,但都没用!workerOne函数中的ok关闭频道并结束等待,但仍然有相同的错误,因为您正在使用的软件包已被弃用,取而代之的是Go附带的软件包。你应该改用。目前,您使用的软件包也没有给您带来任何好处
然而,眼前的问题似乎很明显:运行workerOne的单一goroutine从一个通道读取数据,只有当通道关闭,ok变为false时,它才会调用bar.Fall来消除障碍。同时,运行匿名发送方函数的单个goroutine:
go func() {
for i := 0; i < 5; i++ {
d.x = i
log.Printf("Sending %v", d)
b.Submit(d)
}
<-bar.Barrier()
b.Close()
}()
您在主goroutine中通过sync.WaitGroup变量等待:
w.Wait()
运行匿名发件人功能的gopher正在等待:
<-bar.Barrier()
这三只在各种围棋程序中运行或等待的地鼠中,谁会向匿名发送者中的地鼠发出信号,v,ok:=你有一个工作者和一个通道,但你有所有这些额外的东西-你想在这里做什么?你为什么用广播?为什么要使用barrier,它在自述文件中说它已被弃用?一般来说,会发生死锁,因为所有的goroutine都在等待其他goroutine,这意味着它们都无法继续。这些第三方库的使用超过了内置的langauge结构,这使得我们很难判断到底是什么原因导致了这种情况,以及您试图实现什么。@Adrian我正在学习广播,以便稍后在我的项目中使用它,所以我试图先理解它,当b.提交结束brodcast并在工作前关闭时,这是一个问题函数receive all message,因此我使用了屏障来防止它在workerOne函数get all message之前关闭。我不建议使用不推荐使用的库。看看广播,我也不能说我会推荐它;为了节省一两行代码,它牺牲了类型安全性,这是一个非常大的代价,只需付出很少的好处。
w.Wait()
<-bar.Barrier()