由买买提看人间百态

boards

本页内容为未名空间相应帖子的节选和存档,一周内的贴子最多显示50字,超过一周显示500字 访问原贴
Programming版 - go里面channel和wait group用法比较
相关主题
[bssd] Go 的大并发处理网络碰到两个个问题发现一个Go的大坑,传给defer的参数不取运行时的值
Golang的promise lib哪个好?golang虽然不会一统江湖,但是,干掉python ,ruby是迟早的事情
写backend的朋友还是可以关注一下golanggo也是三种paradigm混合的语言
我来说说go的目标对手吧用golang实现了map,大牛给看看?
golang的问题是channel, goroutine里面magic太多,golang的method是后来加的?
从coffee,scala等到golang效率下降了好几倍怎样能把go写的稍微漂亮一点?
Go的并发和channel看上去非常厉害啊为什么大家不喜欢golang的switch?
golang為什麼語法和關鍵詞這麼冷門?最近学了一下 Go
相关话题的讨论汇总
话题: channel话题: ch话题: func话题: go话题: wait
进入Programming版参与讨论
1 (共1页)
s********k
发帖数: 6180
1
感觉两种sync方法差不多,不太了解两者用起来差别在哪里,比如下面这个简单例子
1,用channel
ch := make(chan int,n)
for i:=0; i < n; i++ {
go func() {
// do something
ch <- i
}
}
for i:=0; i < n; i++ {
<- ch
}
2. 用wait group
var wg WaitGroup
wg.Add(n)
for i:=0; i < n; i++ {
go func() {
defer wg.Done()
// do something
}
}
wg.Wait()
效果来说应该差不多,也许性能有点差异暂时可以忽略,但是两者方法来说有什么显著
差别吗?
f*******o
发帖数: 1
2
个人觉得第一种做法并不实用因为这里知道你需要从chan等的数据的个数, 实际中很少
是这样
我经常做的是把waitGroup放到consumer而不是producer。主线程spin producer和
consumer之后用wg等待。 producer在完成向chan输送数据之后close(ch),而consumer
通过测试<-ch的第二个返回值来决定是否还有data (data, ok := <-ch),没有data之
后wg.Done()来告诉主线程是否结束等待。
第一个例子还有个很tricky的错误,ch <- i 这个 i 在循环的时候一直在改变,所以
在go func里面的传给ch的时候 i 已经是下一个甚至几个循环的值,所以很可能传了一
堆n-1给ch,正确的用法是传值go func(i int) {...}(i)。例子里面go func(){}之后
缺了()可能是促成这个错误的原因。
w********m
发帖数: 1137
3
我感觉他们的场景不一样。
blocking channel 见到的,是用在只有一个go routine的情况。
而wg.Wait用在多个go rountine。
还有一个方法就是楼上说的,close channel。
s********k
发帖数: 6180
4
如果我知道这个chan的个数的话,两者相比起来哪个比较好?因为我没有专门close
channel,最后是不是GC会自动回收那部分?听起来这样的额话用wait group好一点?

consumer

【在 f*******o 的大作中提到】
: 个人觉得第一种做法并不实用因为这里知道你需要从chan等的数据的个数, 实际中很少
: 是这样
: 我经常做的是把waitGroup放到consumer而不是producer。主线程spin producer和
: consumer之后用wg等待。 producer在完成向chan输送数据之后close(ch),而consumer
: 通过测试<-ch的第二个返回值来决定是否还有data (data, ok := <-ch),没有data之
: 后wg.Done()来告诉主线程是否结束等待。
: 第一个例子还有个很tricky的错误,ch <- i 这个 i 在循环的时候一直在改变,所以
: 在go func里面的传给ch的时候 i 已经是下一个甚至几个循环的值,所以很可能传了一
: 堆n-1给ch,正确的用法是传值go func(i int) {...}(i)。例子里面go func(){}之后
: 缺了()可能是促成这个错误的原因。

s********k
发帖数: 6180
5
对的,我没有写明白,第一个应该用closure这样的,go func(i int) {...}(i),我现
在并没有出BUG,只是想知道两种方法比较哪种合适?

consumer

【在 f*******o 的大作中提到】
: 个人觉得第一种做法并不实用因为这里知道你需要从chan等的数据的个数, 实际中很少
: 是这样
: 我经常做的是把waitGroup放到consumer而不是producer。主线程spin producer和
: consumer之后用wg等待。 producer在完成向chan输送数据之后close(ch),而consumer
: 通过测试<-ch的第二个返回值来决定是否还有data (data, ok := <-ch),没有data之
: 后wg.Done()来告诉主线程是否结束等待。
: 第一个例子还有个很tricky的错误,ch <- i 这个 i 在循环的时候一直在改变,所以
: 在go func里面的传给ch的时候 i 已经是下一个甚至几个循环的值,所以很可能传了一
: 堆n-1给ch,正确的用法是传值go func(i int) {...}(i)。例子里面go func(){}之后
: 缺了()可能是促成这个错误的原因。

s********k
发帖数: 6180
6
假设我现在就一个channel,那么如果不去close但是用完了之后golang的GC会去自己
close并且回收?

【在 w********m 的大作中提到】
: 我感觉他们的场景不一样。
: blocking channel 见到的,是用在只有一个go routine的情况。
: 而wg.Wait用在多个go rountine。
: 还有一个方法就是楼上说的,close channel。

c****f
发帖数: 1102
7
程序结束channel自己就关掉了
其实这个真的很搞
buffed channel不需要等receiver
unbuffed channel一定要有receiver 不然直接deadlock
如果不想知道你channel大小用sync是可以的 但是做法一般就是
把sender和receiver全部做成groutine 主程序自己放个for{}就好了
s********k
发帖数: 6180
8
我这里比如都是buffered channel,感觉好像wait group和channel差不多,有点疑惑
,我看前面说在不知道channel多少input时候用wait group,但是你在wait group也会
指定add的数量啊。本质上和for loop一个意思。
你的程序结束比如我在这个goroutine开的channel,这个goroutine结束之后channel和
其他variable同等被回收了?

【在 c****f 的大作中提到】
: 程序结束channel自己就关掉了
: 其实这个真的很搞
: buffed channel不需要等receiver
: unbuffed channel一定要有receiver 不然直接deadlock
: 如果不想知道你channel大小用sync是可以的 但是做法一般就是
: 把sender和receiver全部做成groutine 主程序自己放个for{}就好了

w********m
发帖数: 1137
9
我的意思是实现一个pattern。比如 https://play.golang.org/p/sYowzPo4kZt

【在 s********k 的大作中提到】
: 假设我现在就一个channel,那么如果不去close但是用完了之后golang的GC会去自己
: close并且回收?

f*******t
发帖数: 7549
10
看起来是等价的。
为啥一定要问出个区别呢,编程就是同样的功能有多种写法啊
相关主题
从coffee,scala等到golang效率下降了好几倍发现一个Go的大坑,传给defer的参数不取运行时的值
Go的并发和channel看上去非常厉害啊golang虽然不会一统江湖,但是,干掉python ,ruby是迟早的事情
golang為什麼語法和關鍵詞這麼冷門?go也是三种paradigm混合的语言
进入Programming版参与讨论
s********k
发帖数: 6180
11
我也是按照等价来默认写code的(针对一个channel并且知道buffer size情况),只是
问一下有没有不了解被忽略的区别

【在 f*******t 的大作中提到】
: 看起来是等价的。
: 为啥一定要问出个区别呢,编程就是同样的功能有多种写法啊

f*******t
发帖数: 7549
12
说不定waitgroup就是这么实现的

【在 s********k 的大作中提到】
: 我也是按照等价来默认写code的(针对一个channel并且知道buffer size情况),只是
: 问一下有没有不了解被忽略的区别

s********k
发帖数: 6180
13
好主意,去看看lib实现

【在 f*******t 的大作中提到】
: 说不定waitgroup就是这么实现的
f*******t
发帖数: 7549
14
看了一下源码,实现还是不一样的

【在 s********k 的大作中提到】
: 好主意,去看看lib实现
s********k
发帖数: 6180
15
对的,我也发现了,我现在觉得两者其实是实用不同场景,而且经常会混合起来一起用

【在 f*******t 的大作中提到】
: 看了一下源码,实现还是不一样的
d********f
发帖数: 8289
16
我一般能用channel的地方不用wait group

【在 s********k 的大作中提到】
: 感觉两种sync方法差不多,不太了解两者用起来差别在哪里,比如下面这个简单例子
: 1,用channel
: ch := make(chan int,n)
: for i:=0; i < n; i++ {
: go func() {
: // do something
: ch <- i
: }
: }
: for i:=0; i < n; i++ {

1 (共1页)
进入Programming版参与讨论
相关主题
最近学了一下 Gogolang的问题是channel, goroutine里面magic太多,
玩go还是要玩OO从coffee,scala等到golang效率下降了好几倍
golang 一个thread safe singleton问题Go的并发和channel看上去非常厉害啊
magagop可以看看这些基本golang scheduler的资料golang為什麼語法和關鍵詞這麼冷門?
[bssd] Go 的大并发处理网络碰到两个个问题发现一个Go的大坑,传给defer的参数不取运行时的值
Golang的promise lib哪个好?golang虽然不会一统江湖,但是,干掉python ,ruby是迟早的事情
写backend的朋友还是可以关注一下golanggo也是三种paradigm混合的语言
我来说说go的目标对手吧用golang实现了map,大牛给看看?
相关话题的讨论汇总
话题: channel话题: ch话题: func话题: go话题: wait