goroutine+channel对于 真·新人 还是太危险了

dahuatttt 2013-10-04 11:30:49
看了无闻的go编程基础视频和叶剑峰的帖子后,感觉goroutine用起来很伤神
http://www.cnblogs.com/yjf512/archive/2012/06/06/2537712.html

代码说话,先来2个例子
func test1_a() {
c := make(chan bool)
go func() {
fmt.Println("done")
<-c
}()
c <- true
}
func test1_b() {
c := make(chan bool)
go func() {
fmt.Println("done")
c <- true
}()
<-c
}
func test1_2a() {
c := make(chan bool,1)
go func() {
fmt.Println("done")
<-c
}()
c <- true
}
func test1_2b() {
c := make(chan bool,1)
go func() {
fmt.Println("done")
c <- true
}()
<-c
}

这里面有一个是不会输出done的,还是很容易能找出来

继续
func test2_a() {
c := make(chan bool)
i := 0
var condition int = 3
go func() {
for {
if i++; i < condition {
//Do Something
c <- true
} else {
//Do Something else
}
}
}()
for v := range c {
fmt.Println(v)
}
}
func test2_b() {
c := make(chan bool, 5)
i := 0
var condition int = 3
go func() {
for {
if i++; i < condition {
c <- true
} else {
//Do Something
}
}
}()
for v := range c {
fmt.Println(v)
}
}
func test2_2a() {
runtime.GOMAXPROCS(2)
test2_a()
}
func test2_2b() {
runtime.GOMAXPROCS(2)
test2_b()
}

大家都是死循环,但有一个是不会输出任何东西的,也是很容易能找出来

但是!当你把他们混合起来的时候就很难一下子看出来,必须经过花精力的推导。
runtime.GOMAXPROCS(N)目前我还没找到作用域限制,他的不小心使用很容易导致程序逻辑并不按照原来的方式跑!如果和他人合作写代码,这bug会藏得很深,因为他们各自代码独立测试下来不一定有问题。

另外,我始终没找出 叶剑峰 博文中下面这段话的依据。
无缓冲的channel:由于c是无缓冲的channel,因此必须保证取操作<-c 先于放操作c<- 0
...全文
723 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
liutengfeigo 2013-12-06
  • 打赏
  • 举报
回复
无缓冲的channel:由于c是无缓冲的channel,因此必须保证取操作<-c 先于放操作c<- 0
junlinfushi 2013-11-17
  • 打赏
  • 举报
回复
引用 楼主 dahuatttt 的回复:
看了无闻的go编程基础视频和叶剑峰的帖子后,感觉goroutine用起来很伤神 http://www.cnblogs.com/yjf512/archive/2012/06/06/2537712.html 代码说话,先来2个例子
func test1_a() {
	c := make(chan bool)
	go func() {
		fmt.Println("done")
		<-c
	}()
	c <- true
}
func test1_b() {
	c := make(chan bool)
	go func() {
		fmt.Println("done")
		c <- true
	}()
	<-c
}
func test1_2a() {
	c := make(chan bool,1)
	go func() {
		fmt.Println("done")
		<-c
	}()
	c <- true
}
func test1_2b() {
	c := make(chan bool,1)
	go func() {
		fmt.Println("done")
		c <- true
	}()
	<-c
}
这里面有一个是不会输出done的,还是很容易能找出来 继续
func test2_a() {
	c := make(chan bool)
	i := 0
	var condition int = 3
	go func() {
		for {
			if i++; i < condition {
				//Do Something
				c <- true
			} else {
				//Do Something else
			}
		}
	}()
	for v := range c {
		fmt.Println(v)
	}
}
func test2_b() {
	c := make(chan bool, 5)
	i := 0
	var condition int = 3
	go func() {
		for {
			if i++; i < condition {
				c <- true
			} else {
				//Do Something
			}
		}
	}()
	for v := range c {
		fmt.Println(v)
	}
}
func test2_2a() {
	runtime.GOMAXPROCS(2)
	test2_a()
}
func test2_2b() {
	runtime.GOMAXPROCS(2)
	test2_b()
}
大家都是死循环,但有一个是不会输出任何东西的,也是很容易能找出来 但是!当你把他们混合起来的时候就很难一下子看出来,必须经过花精力的推导。 runtime.GOMAXPROCS(N)目前我还没找到作用域限制,他的不小心使用很容易导致程序逻辑并不按照原来的方式跑!如果和他人合作写代码,这bug会藏得很深,因为他们各自代码独立测试下来不一定有问题。 另外,我始终没找出 叶剑峰 博文中下面这段话的依据。 无缓冲的channel:由于c是无缓冲的channel,因此必须保证取操作<-c 先于放操作c<- 0
危险就别乱玩了
一句话概括: 由业余家谱爱好者基于Microsoft Office平台纯VBA开发,零成本、零门槛,帮你轻松制作媲美专业排印效果的家谱图表,还能一键生成网页版实现网络分享。 核心功能: 纯VBA代码开发,只要安装完整版MS Office即可运行(需支持Access数据库引擎)。 自动生成EXCEL格式的家谱图表,支持三种主流排版模式: 吊线图:直观呈现血缘脉络。 现代排版:适合打印装订的清晰版式。 欧式排版:传统家谱风格,保留古韵。 生成的排版结果完全可改可调,基于Excel单元格自由编辑调整。 新增重磅功能:支持生成静态HTML网页家谱,无需服务器、无需技术背景,直接双击打开就能分享给亲友查阅。 为什么选择丝连族谱? 零成本:基于Office开发,无需购买专业排版软件。 低门槛:纯VBA代码一键执行,不懂编程也能上手。 高自由度:生成的是标准Excel文件,可随意修改调整。 易分享:静态网页版可直接通过微信、U盘等方式传播,适合家族内部查阅。 使用前必读: 本工具基于Microsoft Office(含Access数据库引擎)开发,需要完整版Office支持。 32位Office 2010 及以上版本兼容;64位Office需使用2019及以上版本。 适用人群: 想修家谱但不想学专业排版软件的普通人 | 需要快速生成多份图表的分支编委 | 想将家谱数字化分享给亲友的家族传承者。

2,351

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • 俺叫西西弗斯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧