两个 goroutine:go1,go2
go1 从 socket 读,读到的数据写到 ch1
go2 从 ch2 读,读到的数据写到 socket
以此来实现全双工通信
问题:ch1 关闭之后,go1 不知道,一写就崩了,怎么避免?
1
shakeyo 2021-04-27 16:35:39 +08:00
创建一个用于通知的 chan
for 循环里监听这个 chan 是否有消息 在关闭的时候写入 在读取的时候监听 有信号退出当前 channel 就行 |
2
bfdh 2021-04-27 16:40:34 +08:00 18
溴 ( xiù ) (英語:Bromine )是一種化學元素,其化學符號为 Br,原子序數为 35 —— 摘自维基百科
|
3
hwdef 2021-04-27 16:41:31 +08:00
从 ch 读的时候,可以检查是否已关闭了。
|
4
brader 2021-04-27 16:43:28 +08:00
这确实是个问题,需要今晚好好研究下
|
5
masterclock 2021-04-27 16:47:10 +08:00 7
chan 仅由写的一方关闭
|
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 } ``` |
7
keepeye 2021-04-27 16:48:53 +08:00 1
ch1 由 go1 关闭,也就是永远由写的一方关闭 channel
|
8
lbingl 2021-04-27 16:49:50 +08:00 via Android 3
糗 qiǔ,溴 xiù
|
9
juzisang 2021-04-27 16:52:23 +08:00 2
秀大了
|
10
linvon 2021-04-27 16:53:06 +08:00
go1 来关闭啊,怎么可能由消费者去关闭通道
go2 用 for range 去读,也能感知到关闭 |
11
echo1937 2021-04-27 16:54:10 +08:00 5
你打标题的时候,又糗大了了一次。
|
12
Latin 2021-04-27 16:58:14 +08:00
我怀疑你是套娃 给自己问问题
|
13
name1991 2021-04-27 17:13:56 +08:00
女同事很会发现问题
|
14
Presbyter 2021-04-27 17:16:52 +08:00
可以考虑用 context Cancel 控制一下
go1(ctx){ ... select{ case <-ctx.Done(): return ...... } ..... } |
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 |
16
yogogo 2021-04-27 17:19:25 +08:00
娶回家
|
17
lasuar 2021-04-27 17:22:56 +08:00
5 楼就是答案
|
18
zhaohua 2021-04-27 17:49:14 +08:00
如果把问题简化为: 从关闭的 ch 中读取数据,如何才能不崩溃,答案是:做不到.
|
19
2kCS5c0b0ITXE5k2 2021-04-27 18:05:35 +08:00 1
你又可以发一贴 在 V2EX 发帖 认错字了 糗大了
|
20
Vegetable 2021-04-28 09:54:35 +08:00
没人提但是我很好奇,panic 了就 recover 一下不也算方案吗
|
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 |
22
rekulas 2021-04-30 13:13:56 +08:00
用指针应该有办法判断,但并不是好办法,最好还是听楼上的意见自己处理关闭
|
23
iceteacover 2021-05-14 14:23:57 +08:00
我是来抖机灵的:
不要把问技术问题女性当成女性。 不抖机灵的: 技术面前人人平等,请先尊重你同事的专业能力,再尊重性别。 |
24
Lihanx9 2021-06-08 10:51:06 +08:00
如果是针对这个场景,不要求必须使用 channel 的话。goroutine 里用 io.Copy 读写,根据返回值或者异常判断结束退出 goroutine,另外 io.Copy 用在 net.Conn 上的时候,底层会调用 sendfile,零拷贝效率可能还会高一点。这是我最近遇到这个问题用的方法,不知道对不对啊...
|
25
cyrivlclth 2021-06-24 11:06:09 +08:00
@zhaohua 读取被关的 channel 不会崩。。。写才会
|