Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/go/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在Go频道为空之前取消订阅?_Go_Concurrency_Parallel Processing_Channel - Fatal编程技术网

如何在Go频道为空之前取消订阅?

如何在Go频道为空之前取消订阅?,go,concurrency,parallel-processing,channel,Go,Concurrency,Parallel Processing,Channel,我不明白为什么这个代码不起作用: 游乐场回复: 包干管 进口 fmt 日志 同步 时间 类型事件结构{ 消息字符串 消费者字符串 } func NewEventmsg字符串,使用者字符串事件{ 返回事件{ 讯息:msg,, 消费者:消费者,, } } 类型代理结构{ 消费者映射[chan事件]字符串 mtx*sync.Mutex } func main{ 经纪人:=新经纪人 围棋{ 为了{ time.Sleeptime.Second*1 broker.PublishNewEvent1的消息,1

我不明白为什么这个代码不起作用:

游乐场回复:

包干管 进口 fmt 日志 同步 时间 类型事件结构{ 消息字符串 消费者字符串 } func NewEventmsg字符串,使用者字符串事件{ 返回事件{ 讯息:msg,, 消费者:消费者,, } } 类型代理结构{ 消费者映射[chan事件]字符串 mtx*sync.Mutex } func main{ 经纪人:=新经纪人 围棋{ 为了{ time.Sleeptime.Second*1 broker.PublishNewEvent1的消息,1 broker.PublishNewEvent为所有人发送消息, } } 时间。睡眠2*时间。秒 围棋{ ch:=broker.Subscribe1 ReceivedMgs:=0 为了{ msg:=我正在向客户端浏览器发送消息 //如果u,错误:=w.Write[]bytefmt.Sprintfdata:%s\n\n,msg;err!=nil{ //log.Printlnerr //返回 //} //-->在这里,我取消订阅,如果w.Flush浏览器中的错误被关闭 //如果错误:=w.Flush;错误!=nil{ //日志。打印浏览器已关闭 //经纪人,退订 //返回 //} 收到log.Printlnmessage:,msg.Message 如果收到DMSG>3{ 经纪人,退订 打破 } 接收DMSG++ log.printlreceivedmsgs:,receivedMsgs } } 选择{} } func NewBroker*经纪人{ 退货与经纪人{ 消费者:makemap[chan事件]字符串, mtx:newsync.Mutex, } } func b*代理订阅字符串chan事件{ b、 锁 延迟b.mtx.Unlock c:=makechan事件 b、 消费者[c]=id log.Printlnfmt.Sprintfclient%s已连接,id为 返回c } func b*经纪人取消订阅chan事件{ b、 锁 延迟b.mtx.Unlock id:=b.消费者[c] 克洛塞克 删除b.消费者,c log.Printfclient%s已终止,剩余%d\n,id,lenb.consumers } func b*代理发布事件{ b、 锁 延迟b.mtx.Unlock pubMsg:=0 对于s,id:=范围b{ 如果e.消费者!={ //推送至特定消费者 如果id==e.消费者{ s 3{ 它起作用了

我想问题是因为当我呼叫break时,ch频道中仍然有一条消息

我说得对吗

如何解决这个问题


我的灵感来源于

问题在于空选择。根据本网站,当使用空选择时,select语句将永远阻塞,因为没有goroutine可提供任何数据


为了解决这个问题,我添加了一个带有cancel的上下文,这将允许我在取消订阅时停止底部选择并停止第一个goroutine,我删除了不必要的互斥,因为你正在使用通道,这应该是线程安全的。我还将MSG一个接一个地执行,就像我将两者都放在同一个goroutine上发送一样,这将导致并发,我可以向封闭频道发送消息。

您没有真正描述什么有效,什么无效,这是您的示例。您显示的错误是您所说的行为的结果,您可以通过游乐场示例确认这一点,但通过对所做更改的描述直接与此相矛盾。我如果您确实想在第三条消息后退出,请在检查之前增加计数器。
2009/11/10 23:00:01 published message to 0 subscribers
2009/11/10 23:00:01 published message to 0 subscribers
2009/11/10 23:00:02 client 1 connected
2009/11/10 23:00:02 published message to 1 subscribers
2009/11/10 23:00:02 message received: a message for 1
2009/11/10 23:00:02 receivedMsgs: 1
2009/11/10 23:00:02 message received: a message for all
2009/11/10 23:00:02 receivedMsgs: 2
2009/11/10 23:00:02 published message to 1 subscribers
2009/11/10 23:00:03 published message to 1 subscribers
2009/11/10 23:00:03 message received: a message for 1
2009/11/10 23:00:03 receivedMsgs: 3
2009/11/10 23:00:03 message received: a message for all
2009/11/10 23:00:03 receivedMsgs: 4
2009/11/10 23:00:03 published message to 1 subscribers
2009/11/10 23:00:04 published message to 1 subscribers
2009/11/10 23:00:04 message received: a message for 1
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [select (no cases)]:
main.main()
    /tmp/sandbox948233627/prog.go:70 +0xfb

goroutine 6 [chan send]:
main.(*Broker).Publish(0xc000010240, 0x4c9815, 0x11, 0x0, 0x0)
    /tmp/sandbox948233627/prog.go:121 +0x2af
main.main.func1(0xc000010240)
    /tmp/sandbox948233627/prog.go:34 +0x91
created by main.main
    /tmp/sandbox948233627/prog.go:30 +0xc7

goroutine 7 [semacquire]:
sync.runtime_SemacquireMutex(0xc000018054, 0x0, 0x1)
    /usr/local/go-faketime/src/runtime/sema.go:71 +0x47
sync.(*Mutex).lockSlow(0xc000018050)
    /usr/local/go-faketime/src/sync/mutex.go:138 +0x105
sync.(*Mutex).Lock(...)
    /usr/local/go-faketime/src/sync/mutex.go:81
main.(*Broker).Unsubscribe(0xc000010240, 0xc000062060)
    /tmp/sandbox948233627/prog.go:93 +0x1c5
main.main.func2(0xc000010240)
    /tmp/sandbox948233627/prog.go:61 +0x1a5
created by main.main
    /tmp/sandbox948233627/prog.go:40 +0xf6