1
unixeno 2020-04-11 11:43:42 +08:00 via Android
chan
|
2
useben 2020-04-11 11:47:59 +08:00
chan 就是你说的特性...
|
3
lithbitren OP |
4
DCCooper 2020-04-11 12:03:12 +08:00 via iPhone
@lithbitren #3 buffer ?
|
5
felix021 2020-04-11 12:05:42 +08:00
go 的 channel 貌似底层实现用的还是锁,github 上有第三方的 lockfree ring buffer,具体叫啥忘了,可以搜一下。
|
6
lithbitren OP @DCCooper 是说类似于 make(chan int 10)这种写法吗?
|
7
susecjh 2020-04-11 12:08:29 +08:00
@lithbitren make(chan int, 10)这样不就是定容吗
|
8
feelinglucky 2020-04-11 12:08:30 +08:00
@lithbitren 定容的意思是固定容量吗?或者并发数?那直接设个长度不就好了吗…
|
9
lithbitren OP chan 还有问题,不知道无法监控容量情况,而且也只是实现了 fifo,实现 filo 和优先队列似乎也挺麻烦。
|
10
reus 2020-04-11 12:10:08 +08:00
思而不学
|
11
zhs227 2020-04-11 12:27:36 +08:00
你说的这个可以参考一下 buffered chan 。申请 chan 的时候指定长度即可。
ch := make(chan []struct{}, 1000) 监控容量情况更是简单,len(ch)就是当前队列中未处理容量。 |
12
lithbitren OP |
13
lithbitren OP 用了 sync.WaitGroup 才能让程序停下来,等待死锁报错的出现。
|
14
lithbitren OP @reus 大佬教训的是。
|
15
lithbitren OP 因为之前用 python 比较多,队列、栈、堆在标准库都是有实现的,全部仍在子线程里也会因为定容死锁会导致程序无法关闭,被 go 的一些特性迷惑了,还需要进一步理解 go 。
队列的问题姑且算是解决了,栈和堆的同步实现似乎也找不到啥资料。 |
16
yuikns 2020-04-11 13:18:54 +08:00 1
队列的话我自己 wrap 了一个。
https://github.com/argcv/stork/blob/master/schd/task_queue.go 如果需要监控 capacity 我可能进一步再在这个 struct 中加 |
17
yuikns 2020-04-11 13:23:26 +08:00
栈和堆其实可以也可以用一个 buffer 实现。不过没有 template 构建一个 general 的东西比较麻烦,go 自己的 pool 居然还是 interface,出入都加个类型切换,感觉有点粗糙。
|
18
shujun 2020-04-11 13:50:19 +08:00 via iPhone
自其实这种 自己封装一个很简单的。
ringbuffer +chan, 比自己加锁效率高 |
19
lithbitren OP @shujun 谢谢大佬提示,ringbuffer 原理倒是没啥问题,在 golang 的具体实现中是把 chan 装进 container 的 ring 里面(还是说直接用数组就行),然后进行转圈原子操作吗?还有 buffer 大小一般怎么设定啊,其他一般语言都是号称无锁实现的,而且就算有管道机制也和 golang 的 chan 不尽相同,golang 实现还有点懵懂。
|
20
lithbitren OP 读了下 ring 的源码,除 interface 好像没啥了,其他环形实现似乎上也没啥区别的样子
|
21
fumeboy 2020-04-12 12:41:46 +08:00 via iPhone
刚好在看 ringbuffer,还在苦恼看不懂它的作用……
|