前言
以前一直认为协程是在read 、 write前先yield让出协程,等待数据到来就resume回来,进行之后的处理,假设使用阻塞io,我只需要在eventloop中的epoll_wait设置timeout依然能够实现异步,所以io是否阻塞对整个协程没有关系(反正在你阻塞前都要让出去的嘛),但这两天写代码的时候仔细想了想发现这种想法是错误的,协程必须使用非阻塞io。
原因
产生如上想法的本身是因为没有考虑到程序存在多线程的情况,当阻塞io执行epoll_wait的时候,当前这个线程会从用户态切换到核心态,并在操作系统内部挂起,这样操作系统就回去执行其他的线程了,那么这个挂起线程里万一有协程超时或者数据处理完毕就没办法继续执行了,得等到epoll_wait超时回到用户态,并且操作系统把cpu切换回这个线程才能执行。