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
...全文
708 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
危险就别乱玩了

2,190

社区成员

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

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