一个C/C++协程库的思考与实现之协程的errno与信号处理

GitHub - DoasIsay/XCoroutine: 一个使用C/C++基于epoll实现的高性能的stackfull协程库,通过HOOK阻塞的系统调用,网络IO事件,协程间的同步事件及定时事件驱动协程的调度,通过汇编完成协程的高速切换,支持海量协程创建,支持协程的动态跨线程负载均衡调度,优先级调度,支持协程的栈上溢出检测及协程的signal信号处理机制,提供不同线程间协程同步协作的互斥量mutex,读写锁,条件变量cond,信号量sem,countDownLatch及用于数据共享的channel等等,总之很好玩,,,

每个线程都有自己的errno,那么协程是否也需要自已的errno?

如果这样写代码,那每个协程要有自已的errno

在hook的系统调用中当io读写不能满足时,就进行协程切换,在io可读写返回到用户代码后继续使用errno,此时的errno可能已经不是协程切换前的errno了,因为期间其它协程也会call系统调用,所以因在hook系统调用的代码中,在协程切换前先保存errno的值,因为协程恢复后会先判断errno,根据errno的值选择是继续读写还是出错返回

但如果在hook的系统调用中一直读写,只有读写到数据或出错才返回,那么协程就不需要自己的errno了,这样写代码,虽然用户用的是非阻塞的系统调用,但在hook的代码中我们还是把它实现成阻塞的,这个阻塞是对协程而言的,一个线程被IO阻塞就会被os调度切换,同样的一个协程被IO阻塞,也会被协程的调度器调度切换,我们要把被hook的阻塞的系统调用仍实现为对协程而言是阻塞的,让用户无法感知到他使用的是非阻塞的接口,让用户可以写同步的代码

但是这样就无法在协程库中检测到协程的退出条件,而提前返回,因此要想办法把协程的退出从用户代码传递到协程库的代码中,也就是hook的系统调用中,请不要使用全局变量isExit这种简单粗爆的方法,我们要尽量实现的优雅一些,这时我终于找到了让协程支持信号处理的理由

实现了协程库后,我第一个为协程实现的feature就是信号处理,为协程实现信号处理的第一个原因就是,当时的协程并不能优雅的退出,我想依靠发送信号来通知协程退出,后来我找到了另一种解决协程退出的问题方法

但现在我觉得把hook的系统调用仍实现为对协程而言是阻塞的是一种不错的想法,但是又不能在协程库中使用用户代码中的isExit变量来检测退出,那只能用信号了,当协程收到信号无论IO是否满足还是在等待一个超时,都会返回被信号中断的错误,在hook的系统调用中检测到错误后以出错返回,于是我们去除了协程的errno也用上了协程的信号处理机制

新的问题又出现了,如果协程关联的fd没有IO事件,协程是不会被调度的,因此协程还是无法返回,仍然是被IO阻塞着,对于这样简单的问题同样要用简单的方法解决,把收到信号的协程放入到runQueue

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值