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函数,简直完美