博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一道关于 goroutine 的面试题
阅读量:2493 次
发布时间:2019-05-11

本文共 724 字,大约阅读时间需要 2 分钟。

问题

package mainimport ( "fmt" "time")func main() {
ch1 := make(chan int) go fmt.Println(<-ch1) ch1 <- 5 time.Sleep(1 * time.Second)}

问:

上面代码输出什么?

是5还是别的呢?

分析

如果代码换成如下:

package mainimport ( "fmt" "time")func main() {
ch1 := make(chan int) go func(){
fmt.Println(<-ch1) }() ch1 <- 5 time.Sleep(1 * time.Second)}

答案:

上面问题是造成死锁
第二种情况是正常输出5

这里说明,go 语句后面的函数调用,其参数会先求值,这和普通的函数调用求值一样。

大意思是说,函数调用之前,实参就被求值好了。

因此这道题目 go fmt.Println(<-ch1) 语句中的 <-ch1 是在 main goroutine 中求值的。这相当于一个无缓冲的 chan,发送和接收操作都在一个 goroutine 中(main goroutine)进行,因此造成死锁。

更进一步,大家可以通过汇编看看上面两种方式的不同。

扩展

此外,defer 语句也要注意。比如下面的做法是不对的:

defer recover()

而应该使用这样的方式:

defer func() {
if v := recover(); v != nil {
_ = fmt.Errorf("PANIC=%v", v) } }()

转载地址:http://gdbrb.baihongyu.com/

你可能感兴趣的文章
C++ const的使用
查看>>
离散卷积的计算
查看>>
从0开始学Java——JSP&Servlet——HttpServletRequest相关的几个路径信息
查看>>
poj2299.4thweek.p.A.归并排序
查看>>
同步Android与PC的时间
查看>>
Nunit2.5.10快速上手
查看>>
Cookie 与Session 的区别
查看>>
基于word API 创建的可以打开word的自定义控件
查看>>
tomcat源码 Connector
查看>>
Understanding NFS Caching
查看>>
纯css改变下拉列表select框的默认样式
查看>>
Microsoft Dynamics CRM 前瑞开发
查看>>
html5中的一些标签学习总结
查看>>
Leaflet中添加的不同图层样式图标
查看>>
需求管理
查看>>
Android Listview 性能优化
查看>>
JQuery中this指向
查看>>
Ubuntu 16.04安装idea
查看>>
记录在Spring-Boot中使用Fegin调用RESTfull的PATCH方法设置
查看>>
PostgreSQL增强版命令行客户端(pgcli)
查看>>