草庐IT

go - 广播公司 : all goroutines are asleep - deadlock

coder 2023-06-27 原文

下面的代码 ( http://play.golang.org/p/ikUtdoKOo5 ) 应该向多个客户端广播一条消息。但它不起作用,我不明白为什么。

package main

import "fmt"

type Broadcaster struct {
    Clients []Client
}

func (b *Broadcaster) Broadcast(msg string) {
    for _, c := range b.Clients {
        go func() {
            c.Inbox() <- msg
        }()
    }
}

type Client interface {
    Inbox() chan string
}

type TestClient struct {
    Messages chan string
}

func (tc TestClient) Inbox() chan string {
    return tc.Messages
}

func main() {
    client1 := TestClient{Messages: make(chan string)}
    client2 := TestClient{Messages: make(chan string)}
    broadcaster := Broadcaster{Clients: []Client{client1, client2}}

    broadcaster.Broadcast("sos")

    fmt.Printf("client1: '%s'\n", <-client1.Messages)
    fmt.Printf("client2: '%s'\n", <-client2.Messages)
}


错误:

go run main.go
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
        /Users/artem/projects/gocode/src/github.com/artemave/broadcaster/main.go:36 +0x1f3

goroutine 3 [chan send]:
main.func·001()
        /Users/artem/projects/gocode/src/github.com/artemave/broadcaster/main.go:12 +0x5f
created by main.(*Broadcaster).Broadcast
        /Users/artem/projects/gocode/src/github.com/artemave/broadcaster/main.go:13 +0xcd

goroutine 4 [chan send]:
main.func·001()
        /Users/artem/projects/gocode/src/github.com/artemave/broadcaster/main.go:12 +0x5f
created by main.(*Broadcaster).Broadcast
        /Users/artem/projects/gocode/src/github.com/artemave/broadcaster/main.go:13 +0xcd


更新:

go vet工具揭示了问题:

% go vet
main.go:12: range variable c enclosed by function

最佳答案

这是在 for-range 循环中重新分配 c 引起的一个微妙错误。看起来有点奇怪,但是您在 std 库中的几个地方看到了这种模式:

func (b *Broadcaster) Broadcast(msg string) {
    for _, c := range b.Clients {
        c := c  // redeclare c for the closure
        go func() {
            c.Inbox() <- msg
        }()
    }
}

http://golang.org/doc/faq#closures_and_goroutines

关于go - 广播公司 : all goroutines are asleep - deadlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23922682/

有关go - 广播公司 : all goroutines are asleep - deadlock的更多相关文章

  1. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

  2. ruby-on-rails - Rails 3 和 ActiveAdmin。过滤器显示对象而不是公司名称 - 2

    我有一个客户列表,但在右栏的过滤器部分,我得到一个这样的列表#在选择菜单中。如何改为显示Customer的company_name属性? 最佳答案 明白了,谢谢!filter:customer,:collection=>proc{(Customer.all).map{|c|[c.company_name,c.id]}} 关于ruby-on-rails-Rails3和ActiveAdmin。过滤器显示对象而不是公司名称,我们在StackOverflow上找到一个类似的问题:

  3. ruby-on-rails - 用于 Ruby 的 vim 中的全局 "Go to definition"? - 2

    自97年以来我一直在使用vi/vim进行各种快速编辑和管理任务,但最近才考虑使用它来替换Netbeans作为我选择的ruby​​编辑器。我发现一件事在Netbeans和Eclipse中非常有用的是Ctrl+Click“转到定义”功能,您可以在其中按住Ctrl键并单击一个类或方法,然后它将带您了解定义。现在,我玩过丰富的ctags和rails.vim,而且很接近,但没有雪茄。这就是我想要的:默认情况下在Netbeans和Eclipse中,您可以在本地rails中按住ctrl并单击本地方法或类项目,但你也可以ctrl+click定义在gems或用Ruby编写的系统库。以Netbeans为例

  4. ruby-on-rails - Rails 上的 ruby : How to have multiple submit buttons going to different methods (maybe with with_action? ) - 2

    这个问题在这里已经有了答案:HowdoIcreatemultiplesubmitbuttonsforthesameforminRails?(7个答案)关闭9年前。所以..'save'%>'library'%>然后在我的Controller中:with_actiondo|a|a.savedoenda.librarydoendend问题是只有一个操作被调用...两个submit_tags调用相同的操作...知道为什么吗?或者我如何获得两个按钮以将表单提交给两种不同的方法?

  5. ruby - 公司目录的 LinkedIn API - 2

    我正在尝试使用LinkedInAPI搜索公司,而不是用户。我特别不想要用户-只有公司。我查看了LinkedInAPI文档(RTFM等),但据我所知它不受支持。论坛上有2个帖子几乎直截了本地说明了这一点-here和here我基本上只是在寻找一个简单的搜索界面,类似于LinkedIn主页上正在发生的事情。我还想以某种方式显示返回的信息。我是否最好只对网站本身进行手动GET操作?我需要缓存结果吗?我需要手动解析返回的HTML吗?我计划在Ruby中实现它,但这并不是我真正关心的。 最佳答案 更新:现在有一个官方API:https://dev

  6. DiFi: A Go-as-You-Pay Wi-Fi Access System 精读笔记(三) - 2

    IV.SYSTEMIMPLEMENTATIONWeadoptmodulardesignfollowingtheintegrationofblockchain.Itbringsmoreflexibilitybyseparatingtheimplementationofdifferentfunctionalities,sowecouldleveragetheadvantagesoftheblockchain-basedsmartcontractwhilereducingoverhead.Figure3illustrateshowdifferentmodulesareinvolvedintheint

  7. go-templates - 如何根据表达式有条件地在 Go 模板中设置变量,如果不使用 if 语句包装可能会导致错误 - 2

    问题我该如何做这样的事情:{{$use_ssl:=(ne$.Env.CERT_NAME"")}}其中$.Env.CERT_NAME可能为零/未定义。如果它是零,它给出这个错误:at:errorcallingne:invalidtypeforcomparison注意:我无法控制传递给Go模板的对象,因此必须完全在模板本身内解决这个问题。我尝试过的我试图通过首先检查它是否为非空来变通:{{$use_ssl:=(($.Env.CERT_NAME)&&(ne$.Env.CERT_NAME""))}}但它给出了这个错误:unexpected"&"inoperand所以我切换到这个,这在语法上是允

  8. Go time与string的相爱相杀 - 2

    time包与string包可以说是在Go语言的开发中常用的两个包实际开发过程中(例如web开发)经常会遇到time类型与string类型的交互,计算比较等场景首先来了解GO语言里非常浪漫的一个点,即2006-01-0215:04:05,GO语言诞生的时间,通常用来做时间的格式化time转stringt:=time.Now()//当前时间timeLayoutStr:="2006-01-0215:04:05"t.Format(timeLayoutStr)//返回值为string,可以用一个值来接收它上述例子中,将time类型t转换为string类型,并格式化为年-月-日时-分-秒,这里的格式化是可

  9. javascript - AngularJS 指令 - 从 $rootscope 接收广播 - 2

    我有以下代码,HTMLJSvartest=angular.module('test',[]);test.controller('containerCtrl',['$scope','$rootScope',function($scope,$rootScope){$scope.components=[];$scope.$on('onSomething',function(e){$scope.components=$rootScope.config;});}]);test.directive('component',function(){varlinkFn=function(scope,el

  10. javascript - 使用哈希 url 卡在 Angular ui-router State.go 上? - 2

    我正在研究ui-router。我有一个状态:.state('new-personal-orders',{url:'/orders/new-personal-orders/:catId?',template:''})在我的Controller中,我可以使用$state.go('new-personal-orders',null,{reload:true})在Html文件中我有一个anchor标记:Link如果标签被点击,状态就会改变,'new-personal-orders'变成当前状态,在url中有尾随散列。然后url看起来像:http://localhost:3000/orders/

随机推荐