女同事问了一个 golang 的技术问题,没答上来,溴大了 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
nmap
V2EX    Go 编程语言

女同事问了一个 golang 的技术问题,没答上来,溴大了

  •  
  •   nmap 2021-04-27 16:26:27 +08:00 6422 次点击
    这是一个创建于 1637 天前的主题,其中的信息可能已经有所发展或是发生改变。

    两个 goroutine:go1,go2
    go1 从 socket 读,读到的数据写到 ch1
    go2 从 ch2 读,读到的数据写到 socket
    以此来实现全双工通信

    问题:ch1 关闭之后,go1 不知道,一写就崩了,怎么避免?

    25 条回复    2021-06-24 11:06:09 +08:00
    shakeyo
        1
    shakeyo  
       2021-04-27 16:35:39 +08:00
    创建一个用于通知的 chan
    for 循环里监听这个 chan 是否有消息
    在关闭的时候写入
    在读取的时候监听
    有信号退出当前 channel 就行
    bfdh
        2
    bfdh  
       2021-04-27 16:40:34 +08:00   18
    溴 ( xiù ) (英:Bromine )是一化元素,其化符为 Br,原子序为 35 摘自维基百科
    hwdef
        3
    hwdef  
       2021-04-27 16:41:31 +08:00
    从 ch 读的时候,可以检查是否已关闭了。
    brader
        4
    brader  
       2021-04-27 16:43:28 +08:00
    这确实是个问题,需要今晚好好研究下
    masterclock
        5
    masterclock  
       2021-04-27 16:47:10 +08:00   7
    chan 仅由写的一方关闭
    bruce00
        6
    bruce00  
       2021-04-27 16:48:32 +08:00
    [How to Gracefully Close Channels]( https://go101.org/article/channel-closing.html)

    ```go
    func SafeSend(ch chan T, value T) (closed bool) {
    defer func() {
    if recover() != nil {
    closed = true
    }
    }()

    ch <- value // panic if ch is closed
    return false // <=> closed= false; return
    }
    ```
    keepeye
        7
    keepeye  
       2021-04-27 16:48:53 +08:00   1
    ch1 由 go1 关闭,也就是永远由写的一方关闭 channel
    PinkPumpkin
        8
    PinkPumpkin  
       2021-04-27 16:49:50 +08:00 via Android   3
    糗 qiǔ,溴 xiù
    juzisang
        9
    juzisang  
       2021-04-27 16:52:23 +08:00   2
    秀大了
    linvon
        10
    linvon  
       2021-04-27 16:53:06 +08:00
    go1 来关闭啊,怎么可能由消费者去关闭通道
    go2 用 for range 去读,也能感知到关闭
    echo1937
        11
    echo1937  
       2021-04-27 16:54:10 +08:00   5
    你打标题的时候,又糗大了了一次。
    Latin
        12
    Latin  
       2021-04-27 16:58:14 +08:00
    我怀疑你是套娃 给自己问问题
    name1991
        13
    name1991  
       2021-04-27 17:13:56 +08:00
    女同事很会发现问题
    Presbyter
        14
    Presbyter  
       2021-04-27 17:16:52 +08:00
    可以考虑用 context Cancel 控制一下
    go1(ctx){
    ...
    select{
    case <-ctx.Done():
    return
    ......
    }
    .....
    }
    SmartKeyerror
        15
    SmartKeyerror  
       2021-04-27 17:19:21 +08:00
    The close built-in function closes a channel, which must be either bidirectional or send-only. It should be executed only by the sender, never the receiver, and has the effect of shutting down the channel after the last sent value is received.

    https://pkg.go.dev/builtin#close
    yogogo
        16
    yogogo  
       2021-04-27 17:19:25 +08:00
    娶回家
    lasuar
        17
    lasuar  
       2021-04-27 17:22:56 +08:00
    5 楼就是答案
    zhaohua
        18
    zhaohua  
       2021-04-27 17:49:14 +08:00
    如果把问题简化为: 从关闭的 ch 中读取数据,如何才能不崩溃,答案是:做不到.
    2kCS5c0b0ITXE5k2
        19
    2kCS5c0b0ITXE5k2  
       2021-04-27 18:05:35 +08:00   1
    你又可以发一贴 在 V2EX 发帖 认错字了 糗大了
    Vegetable
        20
    Vegetable  
       2021-04-28 09:54:35 +08:00
    没人提但是我很好奇,panic 了就 recover 一下不也算方案吗
    yefuchao
        21
    yefuchao  
       2021-04-28 14:50:42 +08:00
    https://tour.golang.org/concurrency/4

    A sender can close a channel to indicate that no more values will be sent. Receivers can test whether a channel has been closed by assigning a second parameter to the receive expression
    rekulas
        22
    rekulas  
       2021-04-30 13:13:56 +08:00
    用指针应该有办法判断,但并不是好办法,最好还是听楼上的意见自己处理关闭
    iceteacover
        23
    iceteacover  
       2021-05-14 14:23:57 +08:00
    我是来抖机灵的:

    不要把问技术问题女性当成女性。

    不抖机灵的:

    技术面前人人平等,请先尊重你同事的专业能力,再尊重性别。
    Lihanx9
        24
    Lihanx9  
       2021-06-08 10:51:06 +08:00
    如果是针对这个场景,不要求必须使用 channel 的话。goroutine 里用 io.Copy 读写,根据返回值或者异常判断结束退出 goroutine,另外 io.Copy 用在 net.Conn 上的时候,底层会调用 sendfile,零拷贝效率可能还会高一点。这是我最近遇到这个问题用的方法,不知道对不对啊...
    cyrivlclth
        25
    cyrivlclth  
       2021-06-24 11:06:09 +08:00
    @zhaohua 读取被关的 channel 不会崩。。。写才会
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5410 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 06:58 PVG 14:58 LAX 23:58 JFK 02:58
    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