我试图了解带有默认大小写的选择 block 中关闭 channel 的行为,但对以下输出感到困惑。 这里调用 50 个 goroutines 并关闭结束 channel 。
func testClosedChannelBehavior() {
const n = 50
finish := make(chan bool)
var done sync.WaitGroup
for i := 0; i < n; i++ {
done.Add(1)
go func(x int) {
select {
case <-time.After(1 * time.Hour):
case <-finish:
fmt.Printf("received finish %d\n", x)
default:
fmt.Printf("I didnt wait %d\n", x)
}
done.Done()
}(i)
}
t0 := time.Now()
close(finish)
fmt.Println("finish closed")
done.Wait()
fmt.Printf("Waited %v for %d goroutines to stop\n", time.Since(t0), n)
}
我预计一旦任何 goroutine 打印“received finish”,默认情况不应该被任何其他 goroutine 执行,即“我没有等待”不应该被打印。
但是输出不一致。有时它的行为符合预期,但在多次运行时,我会看到如下所示的意外输出:
=====输出======
我没等 0
收到完成 7
完成关闭
收到完成 13
收到完成 10
收到完成 32
收到完成 5
收到完成 14
收到完成 33
收到完成 42
收到完成 11
收到完成 4
收到完成 23
收到完成 44
收到完成 49
收到完成 15
收到完成 24
收到完成 31
收到完成 16
收到完成 40
收到完成 41
收到 完成 6
收到完成 26
我没等 1
收到完成 19
收到 完成 8
收到完成 43
收到完成 29
收到完成 20
收到完成 46
收到 完成 12
收到完成 36
收到完成 47
收到完成 37
收到完成 35
收到完成 30
收到完成 39
收到完成 22
收到完成 28
我没等 2
收到完成 17
收到完成45
我没等 9
收到完成 48
收到完成 34
我没等 3
收到完成 25
收到完成 38
收到完成 27
收到完成 18
收到完成 21
等待 50 个 goroutine 停止 394.999µs
我正在浏览 this link期望 close(finish) 会向其他仍在等待的人发出类似的信号。
最佳答案
对 fmt.Printf 的调用涉及系统调用。系统调用会自动导致该 goroutine 重新安排,因为它必须等待操作系统完成该系统调用。这意味着其中一些 goroutine 很可能会运行 select 语句并选择默认情况,但尚未打印到控制台。
编辑:此外,如果您在具有多个线程的系统上运行此程序,默认情况下 go 运行时将并行 运行多个 go 例程(匹配操作系统线程的数量),这意味着其中一些 goroutine 可能在 channel 关闭的同时执行,并在主 goroutine 中 channel 关闭发生之前到达 select 语句。
如果您添加同步 channel 以确保 channel 关闭操作发生在 select 发生在任何 goroutine 中,它会按预期工作:
https://play.golang.org/p/XtUYaihKgRT
func testClosedChannelBehavior() {
const n = 50
finish := make(chan bool)
proceed := make(chan struct{})
var done sync.WaitGroup
for i := 0; i < n; i++ {
done.Add(1)
go func(x int) {
<-proceed
select {
case <-time.After(1 * time.Hour):
case <-finish:
fmt.Printf("received finish %d\n", x)
default:
fmt.Printf("I didnt wait %d\n", x)
}
done.Done()
}(i)
}
t0 := time.Now()
close(finish)
fmt.Println("finish closed")
close(proceed)
done.Wait()
fmt.Printf("Waited %v for %d goroutines to stop\n", time.Since(t0), n)
}
关于go - 在具有 select case 和 default 的 Goroutines 中,一旦 channel 关闭,default 不应该被执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48527601/
我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#
下面的代码在我第一次运行它时就可以正常工作:require'rubygems'require'spreadsheet'book=Spreadsheet.open'/Users/me/myruby/Mywks.xls'sheet=book.worksheet0row=sheet.row(1)putsrow[1]book.write'/Users/me/myruby/Mywks.xls'当我再次运行它时,我会收到更多消息,例如:/Library/Ruby/Gems/1.8/gems/spreadsheet-0.6.5.9/lib/spreadsheet/excel/reader.rb:11
我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋
RSpec似乎按顺序匹配方法接收的消息。我不确定如何使以下代码工作:allow(a).toreceive(:f)expect(a).toreceive(:f).with(2)a.f(1)a.f(2)a.f(3)我问的原因是a.f的一些调用是由我的代码的上层控制的,所以我不能对这些方法调用添加期望。 最佳答案 RSpecspy是测试这种情况的一种方式。要监视一个方法,用allowstub,除了方法名称之外没有任何约束,调用该方法,然后expect确切的方法调用。例如:allow(a).toreceive(:f)a.f(2)a.f(1)
我有一个模块stat存在于目录结构中:lib/stat_creator/stat/在lib/stat_creator/stat.rb中,我在lib/stat_creator/stat/目录中有我需要的文件,以及:moduleStatCreatormoduleStatendend当我使用该模块时,我将这些类称为StatCreator::Stat::Foo.new现在我想要一个存在于应用程序中的根Stat类。我在app/models中制作了我的Stat类,并在routes.rb中进行了设置。但是,如果我转到Rails控制台并尝试在应用程序/模型中使用Stat类,例如:Stat.by_use
一段时间以来,我一直在使用open_uri下拉ftp路径作为数据源,但突然发现我几乎连续不断地收到“530抱歉,允许的最大客户端数(95)已经连接。”我不确定我的代码是否有问题,或者是否是其他人在访问服务器,不幸的是,我无法真正确定谁有问题。本质上,我正在读取FTPURI:defself.read_uri(uri)beginuri=open(uri).readuri=="Error"?nil:urirescueOpenURI::HTTPErrornilendend我猜我需要在这里添加一些额外的错误处理代码...我想确保我采取一切预防措施来关闭所有连接,这样我的连接就不是问题所在,但是我
我正在尝试按Rails相关模型中的字段进行排序。我研究的所有解决方案都没有解决如果相关模型被另一个参数过滤?元素模型classItem相关模型:classPriority我正在使用where子句检索项目:@items=Item.where('company_id=?andapproved=?',@company.id,true).all我需要按相关表格中的“位置”列进行排序。问题在于,在优先级模型中,一个项目可能会被多家公司列出。因此,这些职位取决于他们拥有的company_id。当我显示项目时,它是针对一个公司的,按公司内的职位排序。完成此任务的正确方法是什么?感谢您的帮助。PS-我
我有一个super简单的脚本,它几乎包含了FayeWebSocketGitHub页面上用于处理关闭连接的内容:ws=Faye::WebSocket::Client.new(url,nil,:headers=>headers)ws.on:opendo|event|p[:open]#sendpingcommand#sendtestcommand#ws.send({command:'test'}.to_json)endws.on:messagedo|event|#hereistheentrypointfordatacomingfromtheserver.pJSON.parse(event.d