一个C/C++协程库的思考与实现之协程库的正常退出

https://github.com/DoasIsay/ToyCoroutine

我发现协程只能在对端主动断开连接后才能被动退出,并不能主动退出,做为服务端其实不应当主动断开连接退出,你不知道客户端还有没有数据要发,及客户端的发送缓冲区还有没有数据未发完,如果客户端没有在应用层实现ack及重试机制就有可能导致数据丢失,但协程不一定要只用在服务端

思来想去,我还是想,像在多线程,多进程编程环境中那样,在代码中设一全局变量isExit,当 kill进程时,在信号处理函数中设isExit为true时,进程可以正常关闭所有协程,然后出,经测试进程并不能正常退出,在退出时会崩掉

如果分析协程从创建调度运行到返回退出,这条路径的话会发现,

协程都是从startCoroutine函数开始执行,退出后都会返回到startCoroutine中,第一个,第二个,第n-1个协程退出后都会调用schedule函数,让出CPU转移控制权到调度器,这时调度器检测到isExit==true并且所有协程都已经退出了,调度器就会从schedule函数返回,这个函数在整个任务执行期间只有这一次返回,从schedule函数返回后startCoroutine函数也返回,startCoroutine函数也只有任务退出时才会返回一次,但这个返回地址是未知的,因为协程的启动是直接修改了restore函数调用的返回地址为startCoroutine,让restore函数返回时直接跳转到startCoroutine函数执行,并不是调用了startCoroutine函数,相当于jmp过来的,只有调用一个函数,编译器才会生成call指令,才会保存被调用函数的那条指令的下一条指令的地址在函数调用的栈帧上,也就是函数的返回地址,因此当最后一个协程从startCoroutine返回时,这个返回地址是未知的,所以现在我们要使用一个全局变量来保存一个返回地址让最后一个协程能安全的返回到main函数中

比如这样,在scheudler中定义一个全局的retPoint

当第一次调用schedule()函数时也就是在main函数中,保存这个返回地址到retPoint


在最后一个协程从schedule()函数返回后到startCoroutine()函数中时,就restore返回到main函数,简直完美

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值