我正在按照此 tutorial 学习 Go 中的 channel . 当我只向 channel 发送值时,它会出错。这是示例代码。
package main
import "fmt"
func main() {
ch := make(chan int)
ch <- 1
fmt.Println("Does not work")
}
在这里我只是向 channel 发送值但没有收到任何东西。报错
fatal error: all goroutines are asleep - deadlock!
但是当我运行下面的代码时它没有给出任何错误
package main
import "fmt"
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
func main() {
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
fmt.Println("did not receive but still works")
}
并打印
did not receive but still works
我不明白为什么它在第二种情况下有效,而在第一种情况下却不起作用。即使在这两种情况下我都没有收到任何关于 channel 的值(value)。还有是什么导致了第一种情况下的死锁以及如何在第二种情况下避免死锁?
最佳答案
这两个例子都不起作用。事实上,仅发送到 channel 的示例在任何传统意义上的“工作”中都不会工作。
但为了清楚起见,这里有一个步骤:
ch := make(chan int)
这将创建一个无缓冲 channel 。无缓冲 channel 不保存任何数据,它们仅充当通信管道——在程序继续执行之前,所有发送的数据都必须由其他东西接收——在 channel 的任一侧。
ch <- 1
此处您在 channel 上发送数据,但没有任何东西等待接收它,因此程序等待。在这种情况下,它会永远等待,因为您从未为 channel 创建接收者,因此会出现死锁。
c := make(chan int)
再次创建一个无缓冲 channel 。
go sum(s[:len(s)/2], c)
调用 sum 函数,顺便说一句,由于上述原因,该函数也将永远阻塞—— channel 上没有接收任何东西,因此它将永远等待。但是,在这种情况下,您已经在 goroutine 中调用了它。 goroutine 将在单独的执行线程中运行,而程序的其他部分运行。虽然,由于从不从 channel 接收数据,这个 goroutine 永远不会退出,直到主程序退出。
go sum(s[len(s)/2:], c)
再次,您在 goroutine 中调用 sum。所以此时,您有三个 gorotuine:一个运行 main(),另一个运行 sum() 调用。后两者永远不会退出。
然后你的程序退出。当程序退出时,所有 goroutines(包括永远卡在你的 channel 上的两个)退出。
由于该程序立即退出,因此从未报告过死锁,但它确实存在,与您的第一个示例相同。
关于仅向 channel 发送值时进入工作流程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56249851/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo
rails中是否有任何规定允许站点的所有AJAXPOST请求在没有authenticity_token的情况下通过?我有一个调用Controller方法的JqueryPOSTajax调用,但我没有在其中放置任何真实性代码,但调用成功。我的ApplicationController确实有'request_forgery_protection'并且我已经改变了config.action_controller.consider_all_requests_local在我的environments/development.rb中为false我还搜索了我的代码以确保我没有重载ajaxSend来发送
使用Ruby1.9.2运行IDE提示说需要gemruby-debug-base19x并提供安装它。但是,在尝试安装它时会显示消息Failedtoinstallgems.Followinggemswerenotinstalled:C:/ProgramFiles(x86)/JetBrains/RubyMine3.2.4/rb/gems/ruby-debug-base19x-0.11.30.pre2.gem:Errorinstallingruby-debug-base19x-0.11.30.pre2.gem:The'linecache19'nativegemrequiresinstall
我的工作要求我为某些测试自动生成电子邮件。我一直在四处寻找,但未能找到可以快速实现的合理解决方案。它需要在outlook而不是其他邮件服务器中,因为我们有一些奇怪的身份验证规则,我们需要保存草稿而不是仅仅发送邮件的选项。显然win32ole可以做到这一点,但我找不到任何相当简单的例子。 最佳答案 假设存储了Outlook凭据并且您设置为自动登录到Outlook,WIN32OLE可以很好地完成此操作:require'win32ole'outlook=WIN32OLE.new('Outlook.Application')message=
我知道全局变量$!包含最新的异常对象,但我对下面的语法感到困惑。谁能帮助我理解以下语法?rescue$! 最佳答案 此构造可防止异常停止您的程序并使堆栈跟踪冒泡。它还会将该异常作为值返回,这很有用。a=get_me_datarescue$!在此行之后,a将保存请求的数据或异常。然后您可以分析该异常并采取相应措施。defget_me_dataraise'Nodataforyou'enda=get_me_datarescue$!puts"Executioncarrieson"pa#>>Executioncarrieson#>>#更现实的