一般来说 chan 推荐用带缓冲的还是不带缓冲? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
< href="http://play.golang.org/" target="_blank">Go Playground
Go Projects
Revel Web Framework
admirez
V2EX    Go 编程语言

一般来说 chan 推荐用带缓冲的还是不带缓冲?

  •  
  •   admirez 2018-03-15 07:26:7 +08:00 via iPhone 2169 次点击
    这是一个创建于 2772 天前的主题,其中的信息可能已经有所发展或是发生改变。
    18 条回复    2018-03-17 10:38:37 +08:00
    janxin
        1
    janxin  
       2018-03-15 07:28:51 +08:00
    看需求...
    harry890829
        2
    harry890829  
       2018-03-15 08:50:56 +08:00
    搭车问下,我这边想用下协程池,是不是可以利用 chan 的阻塞机制?假设我 10 个协程都在等待 chan,chan 有内容自然就被协程读取了
    snail1988
        3
    snail1988  
       2018-03-15 09:22:49 +08:00
    协程就没必要池了吧,开销很低
    Reset
        4
    Reset  
       2018-03-15 10:09:18 +08:00
    @harry890829 10 个 goroutine 等待一个同一个 chan? 这样只会被某一个 goroutine 执行的
    harry890829
        5
    harry890829  
       2018-03-15 10:11:35 +08:00
    @Reset #4 是啊,这就是目的啊,生产者消费者嘛,我生产者不停的往 chan 加载,消费者 10 个 goroutine 等待 chan,如果 chan 有内容,是不是就被某一个 goroutine 读取,如果 chan 为空,则 goroutine 则进入阻塞状态?
    panyanyany
        6
    panyanyany  
       2018-03-15 10:16:24 +08:00
    @harry890829 #5 那你最好是用带缓冲的 chan,如果不带缓冲的话,你的其他 9 个 goroutine 会被堵住,写不进去。
    zzn
        7
    zzn  
       2018-03-15 10:18:43 +08:00
    @snail1988 开销是很低,但池化的一个好处是不会瞬间创建太多协程导致系统资源不足
    monnand
        8
    monnand  
       2018-03-15 10:35:59 +08:00 via Android
    不带缓存。这样方便收发双方同步。
    missdeer
        9
    missdeer  
       2018-03-15 10:41:09 +08:00
    @harry890829 就是这样
    Reset
        10
    Reset  
       2018-03-15 10:41:25 +08:00
    @harry890829 那你为什么不直接用一个 roroutine 接受 chan, 读取成功后在直接 起一个 goroutine 也可以

    for {
    e := <- ch
    go some_func(e)
    }
    harry890829
        11
    harry890829  
       2018-03-15 11:01:43 +08:00
    @snail1988 #3 还是弄个池吧,我这边外部消息进来不可控,担心量大的时候给冲垮,主要是考虑到协程中还会需要进行数据库、文件等操作,协程可能本身没问题,但是协程量过大把数据库拖垮了就 sb 了
    @panyanyany #6 现在准备用缓冲的 chan 来操作
    @Reset #10 恩恩,大致是这个意思,不过我需要控制 goroutine 的总量,goroutine 中会包含数据库操作,担心后来的操作有影响
    Reset
        12
    Reset  
       2018-03-15 12:04:42 +08:00
    @harry890829 那你也可以使用带容量的 channel 然后根据 len(ch) 加上 sync.WaitGroup 来实现, 不过你的方案如果能行的话效率应该是最高的
    虽然带容量, 在 ch 满了之后会依然是阻塞的, 会导致 producer 不能继续,
    之前做一个服务的时候有种场景 「 producer 可以不断的生产消息, 但是 consumer 需要限制消费速度」 channel 这个时候并是不很适用, 后来使用 slice 加 atomic 做的队列实现的
    JamesRuan
        13
    JamesRuan  
       2018-03-15 13:22:55 +08:00
    pool := make(chan chan Work, poolSize)
    stop := make(chan struct{})
    go func() {
    for {
    waitWork := make(chan work)
    select {
    case <-stop:
    return
    case pool <- waitWork:
    go func() {
    doWork(<-waitWork)
    close(waitWork)
    }()
    }
    }
    }()
    JamesRuan
        14
    JamesRuan  
       2018-03-15 13:24:43 +08:00
    如上。
    带 buffer 的 channel 天然就是一个 pool。
    harry890829
        15
    harry890829  
       2018-03-15 15:33:15 +08:00
    @Reset #12 恩恩,我生产者本身是 kafka 的消费者,所以阻塞的话应该问题不大,到时候我压测一下,结合生产数据量算算
    @JamesRuan #13 pool 是 chan chan 结构?我还没用过这东西,晚点研究研究
    admirez
        16
    admirez  
    OP
       2018-03-15 20:20:27 +08:00
    @JamesRuan 可是 buffer 满了的话 channel 就堵住了
    JamesRuan
        17
    JamesRuan  
       2018-03-17 10:36:54 +08:00
    @admirez 这个就是需求呀。
    buffer 不是为了不堵住的,而是为了控制堵住数量的。独占的话 buffer 就是 0,允许一个等待,buffer 就是 1。
    JamesRuan
        18
    JamesRuan  
       2018-03-17 10:38:37 +08:00
    @harry890829 chan chan 是好东西,外层 chan 带 buffer 排队,内层 chan 同步传具体数据。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     3250 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 36ms UTC 11:15 PVG 19:15 LAX 04:15 JFK 07:15
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86