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 · 6063 次点击
    这是一个创建于 1306 天前的主题,其中的信息可能已经有所发展或是发生改变。

    两个 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
    lbingl
        8
    lbingl  
       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   ·   实用小工具   ·   2530 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 15:29 · PVG 23:29 · LAX 07:29 · JFK 10:29
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.