阻塞与线程
什么是阻塞(block)呢?线程在执行屮如果遇到磁盘读写或网络通信(统称为I/O操作),通常要消耗较长的时间,这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他的工作线程,这种线程调度方式称为阻塞。当I/O操作完毕时,操作系统将这个线程的阻塞状态解除,恢复其对CPU的控制权,令其继续执行。这种I/O模式就是通常的同步式I/O( SynchronousI/O)或阻塞式I/O( Blocking I/O)。
相应地,异步式I/O (Asynchronous I/O)或非阻塞式I/O (Non-blocking I/O)则针对所有I/O操作不采用阻塞的策略。当线程遇到I/O操作时,不会以阻塞的方式等待I/O操作的完成或数据的返回,而只是将I/O 请求发送给操作系统,继续执行下一条语句。当操作系统完成I/O操作时,以事件的形式通知执行I/O操作的线程,线程会在特定时候处理这个事件。为了处理异步I/O,线程必须有事件循环,不断地检查有没有未处理的事件,依次于以处理
单线程事件驱动的异步式I/O比传统的多线程阻塞式I/O究竞好在哪呢?简而言之,异步式I/O就是少了多线程的开销。对操作系统来说,创建一个线程的代价足十分昂贵的,需要给它分配内存、列入调度,同时在线程切换的时候还要执行内存换页? CPU的缓存被被清空,切换回来的时候还要重新从内存中读取倍息.破坏了数据的局部性。
当然,异步式编程的缺点在于不符合人们一般的程序设计思维,容易让控制流变得晦涩难懂,绐编码和调试都带来不小的闲难,习惯传统编程模式的开发者在刚刚接触到大规校的异步式应用时往往会无所适从,但慢慢习惯后会好很多。尽管如此,异步式编程还是较为闲难, 不过可喜的是观在已经有了不少专门解决异步式编程问题的库(如async )。