libgo icon indicating copy to clipboard operation
libgo copied to clipboard

【建议】添加自动调度策略和栈大小动态分配

Open kong123456 opened this issue 3 years ago • 4 comments

对比现有的几个开源库,libgo 的功能和实现是比较完善和比较好的一个。有两点建议,望评估:

  1. 现有的协程库都没有自动调度功能,只有业务层主动调用 网络io、文件io、协程锁metux、yield 等接口时,才会触发协程的切换(调度)。 比如在一个循环里做很耗时的逻辑计算(不会触发协程的切换),就会有可能导致其他协程延迟比较高。当然,业务层可以调用 yield 接口主动切换掉,实际上这样做不太现实,毕竟不是每次都知道要添加一个 yield 调用。 所以能否引入或者借鉴 golang 的协程切换机制,开启一个线程来计算当前协程的时间片,时间片用完就 kill worker线程,在中断处理函数里保存内核记录的寄存器状态,并修改中断结束后的处理函数地址,实现协程自动调度。

  2. 包括 golang 的协程在内,还没实现比较好的栈内存大小动态分配问题。 为了实现海量的协程数,目前业界的做法无非预分配几KB的栈大小,栈内存不够用的时候就将申请一块更大的内存,将原有的栈数据复制过去。这种实现方式有一个不好的地方,如果栈里的指针变量指向了栈中的变量地址,就有可能出现内存非法访问。目前 golang 也是这种实现方式。 所以能否引入或者借鉴内存分配器的机制。预先给栈申请系统默认大小的内存地址空间,注意是内存地址空间,不是物理内存。在协程切换时,判断当前栈使用量是否过小,需要释放出物理内存(linux平台通过 madvise api 实现)。

kong123456 avatar Aug 27 '21 12:08 kong123456

@kong123456 那怎么自己实现一个带时间片的携程调度器。

529124368 avatar Sep 06 '22 10:09 529124368

已收到您的邮件,如有问题会尽快给您回复. 

paradiseforgithub avatar Sep 06 '22 10:09 paradiseforgithub

可是如果实现golang的调度,那么性能就会差很多。

wujin1989 avatar Jan 12 '24 11:01 wujin1989

我个人理解,有个固定时间片的FIFO都比不能调度的好,毕竟绝大部分业务链接都是很快完成,只有业务没考虑到小部分会有长耗时,以致拖垮整个业务。当然了作为工程项目,可以先抽离出接口,提供最基础的实现,后续再逐步完善。

kong123456 avatar Mar 15 '24 09:03 kong123456