[Go] 这两段代码怎么选择喔?

2021-08-03 10:10:31 +08:00
 lysS

select {
case l.rConn <- c:
default:
}

if len(l.rConn) < cap(l.rConn) {
	l.rConn <- c
}


1880 次点击
所在节点    Go 编程语言
15 条回复
index90
2021-08-03 10:27:47 +08:00
当然第一个啊
len(chan) 虽然线程安全的,但很少会这么用,原因是当你前一步执行了 len,下一步就不一定是那个数量了
CEBBCAT
2021-08-03 11:00:07 +08:00
当然是第一种,第二种我都看不懂你要做什么。倒立吃饭的感觉
yeqown
2021-08-03 11:04:22 +08:00
nonblocking send channel ?那肯定是第一种更通用,容易理解
SorcererXW
2021-08-03 12:46:24 +08:00
第二非原子操作,是有问题的
lysS
2021-08-03 14:14:52 +08:00
@index90 主要是考虑到性能问题
BenchmarkSelect-8 82773339 16.42 ns/op 0 B/op 0 allocs/op
BenchmarkLen-8 738067750 1.571 ns/op 0 B/op 0 allocs/op
BenchmarkLenLock-8 35197221 33.51 ns/op 0 B/op 0 allocs/op

而且 l.rConn 只有一处写入,可能有多处读取
lysS
2021-08-03 14:15:58 +08:00
@CEBBCAT 就是非阻塞写入,管道没用容量的话会直接丢弃本次数据
keepeye
2021-08-03 15:13:16 +08:00
第二种不是原子的,两个线程同时判断可能会有一个阻塞
index90
2021-08-03 16:14:52 +08:00
@lysS 你是不是在 select 或者 if 外包了一层 for 啊?
lysS
2021-08-03 18:10:00 +08:00
@index90 对的,在一个循环中,只有这一个地方在写入
sunshinev
2021-08-03 20:41:25 +08:00
第二个一眼看不懂。。。第二眼也没看懂。。
lysS
2021-08-03 20:59:29 +08:00
@sunshinev 这有啥的,就是避免写入阻塞哒
index90
2021-08-03 23:57:58 +08:00
直接让它阻塞在 l.rConn <- c 就好啦,为啥还要 select default 或者 if 来跳过啊。
第二种写法很有可能就会阻塞在 l.rConn <- c 的。
lysS
2021-08-04 08:40:09 +08:00
@index90 逻辑要求就不能阻塞,丢失数据也不能阻塞。

然后 l.rConn 的写入只有这一处,第二种写法也有阻塞的可能?
index90
2021-08-04 10:47:12 +08:00
@lysS 像上面说的,if len(l.rConn) < cap(l.rConn) 和 l.rConn <- c 不是原子的,所以有阻塞可能。你要非阻塞只能用上面的 select
XTTX
2021-08-05 11:20:56 +08:00
能用 switch 就不用 if, Bill Kennedy 的淳淳教诲

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/793307

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX