kcp icon indicating copy to clipboard operation
kcp copied to clipboard

看起来KCP库线程不安全,建议补充这个能力

Open yuanxuewen opened this issue 4 years ago • 8 comments

如果这个库线程不安全,使用起来就不方便了,使用者要考虑加锁互斥,性能就会下降, 建议这个库内部将线程安全做了。

ikcp_update和ikcp_send/ikcp_recv都可以不再一个线程中执行, 另外建议ikcp_recv能支持阻塞,不然上层不好及时处理收到的消息。

yuanxuewen avatar Jan 13 '20 03:01 yuanxuewen

kcp内部并无阻塞,外层自己加锁足够,纯算法库不做系统调用,另最高效的实现是将一组链接的收发全部放在一个线程内异步网络机制实现。

skywind3000 avatar Jan 13 '20 09:01 skywind3000

ARQ内部从来不做线程安全,默认就是上下文一致的环境,并发访问ARQ这种做法本身就是有问题的

caoli5288 avatar Jan 13 '20 09:01 caoli5288

如果只在一个线程上下文中使用,业务模型就和受限了,做不出稍微复杂,高效的业务逻辑。 我感觉底层的收包和ARQ逻辑应该在一个独立的线程中,收发在业务线程中,且ikcp_recv要能支持阻塞,如果使用sleep就不能收包,带宽上不上去,如果while(1),CPU就100%了

yuanxuewen avatar Jan 13 '20 11:01 yuanxuewen

你没写过异步 tcp 网络模型么?reactor 之类的,什么叫做做不出稍微复杂,高效的业务,第一次听过,nodejs/libevent/libev 这些不都是收发再一个线程里面的么?他们做不出复杂的业务?还是你不会写异步逻辑?

我第一次听过复杂业务要用阻塞模式来写,你这属于常识都没有的说法,真正的复杂业务都是非阻塞异步写出来的。

提供阻塞?你需要的话,这是可以封装在你网络层的,协议栈,听过没,别什么东西都想往一个协议单元里加,什么都耦合在一起。

我这么给你说,从设计上来讲,异步非阻塞是比较根本的设计,它可以模拟同步阻塞,同步阻塞在网络协议栈里就是属于 “应用层” 的东西,协议栈上层加个信号量封装下即可实现,而你如果底层架构就是阻塞的,那么对不起,你上面会非常笨拙。

给你一把怎么用都行的瑞士军刀你不干,非要给你一把五岁小孩用的带防夹伤功能的指甲刀你才用的来么?

skywind3000 avatar Jan 13 '20 12:01 skywind3000

@yuanxuewen 你的感觉没什么错,但实现所谓的收包和ARQ逻辑应该在一个独立的线程中,发包在业务线程中不需要显式使用锁,更不需要recv函数支持阻塞,最简单的套个eventloop就能做到,也就是韦先生说的reactor模型,

caoli5288 avatar Jan 13 '20 18:01 caoli5288

kcp属于纯算法逻辑且没有任何的系统调用,每个kcp属于connection,因此锁应该位于外层,而不是算法内部。

shaoyuan1943 avatar Apr 09 '20 04:04 shaoyuan1943

如果这个库线程不安全,使用起来就不方便了,使用者要考虑加锁互斥,性能就会下降, 建议这个库内部将线程安全做了。

ikcp_update和ikcp_send/ikcp_recv都可以不再一个线程中执行, 另外建议ikcp_recv能支持阻塞,不然上层不好及时处理收到的消息。

建议先全面了解一下KCP再下结论,而不是只看看源码、调调接口

gimphammer avatar Apr 18 '20 19:04 gimphammer

...自己控制不是很简单吗。。。

L-LingRen avatar May 05 '21 07:05 L-LingRen