Asynchronous I/O, or non-blocking I/O, is a form of input/output processing that permits other processing to continue before the transmission has finished
非阻塞不一定做到异步。非阻塞只是意味着方法调用不阻塞,但是通过事件通知的方式给调用线程一个机会去完成。它的逻辑是“等可以读(写)了告诉你”。这意味着工作的完成者仍然是调用者(线程)。
而异步不只是意味着方法调用不阻塞,它还意味着工作的完成已经转移到别的线程。意思是,只要你把工作交给了我,工作就“交”给了我。也许你会传个回调函数给我,但是函数的调用仍然是由“我”来完成的。你在发出调用以后,不再需要任何的工作。调用发出了,你的工作就完成了。我的工作开始了。工作转移到我这边。我是下一步。你可以接下去做别的工作。
它的逻辑是“我做完了 告诉/不告诉 你”。它与非阻塞的区别在于:“做完了”。能力来源当然是后台的线程机制。
这种机制,使用起来其实需要相当小心,因为它在现有程序以外自作主张地新开了线程。这显然将影响整个的运行时计划。API不应该拥有执行自己的能力,它们只应该拥有一种能力那就是:被调用!
但是无论如何,它提供了一种真正可能的异步工作模式:你做你的事情,我做我的事情。我们通过一定的通信手段进行合作。合作流程非常清晰。
如果说在异步IO以前,所有的程序必须自行处理IO问题。那么,有了异步IO,程序就彻底从IO的负担中解脱出来了:1,I/O工作被彻底从原有线程中分离出去。原有线程在I/O工作中除了把I/O目的告诉异步I/O API,它不需要做任何额外的工作(为了完成原有的I/O任务);2,I/O工作在独立的线程中完成,不管它有或可能产生任何问题,这种问题也不可能POP UP到调用者线程即代码中去。调用者线程甚至不需要去捕捉任何I/O异常!
问题是:I/O在应用程序中究竟处于或应该处于什么地位?意思是,它是一级公民,还是二级公民?因为为I/O工作启动单独的线程显然意味着它已经处于与程序的其它部分同等重要的地位。
这个问题的核心其实是:对应于两个级别,I/O其实对应的只是两种工作方式:1,被调用;2,被升华成线程。
两者的区别是什么?
把处理器虚拟化的话,调用与线程其实都只不过是处理器所执行的一些代码而已。不管是调用还是线程,其实都是发生在同一个地方:进程内存空间。调用是一种代码协作手段,线程是另一种代码协作手段。只不过第一,线程中的个体,比调用中的个体,传统上的看法,级别要更“高”一些。因为调用者本身其实也是被线程所调用的。因此,一切都可以被看成是被线程所调用的。但是现在I/O变成了单独的线程,它摇身一变,从被调用的代码变成了调用的主宰者。第二,调用是一种纵向的协作模式,线程是一种横向的协作模式。
从工作内容的特性上面看,I/O的确是一种与众不同的工作。它被分出来,是正确的选择。事实上,在进行线程设计的时候,所根据的一个主要划分原则就是工作内容的不同。比如,UI线程经常是与其它线程独立的。
。。。
该如何利用线程?线程到底是什么东西?最终的一切,我觉得还是为了本地性能的最大化。当然有时候性能最大化跟用户目标会有冲突,但基本上,在大部分时候,如果达到了性能的最大化,也就达到了服务性能的提高。也就达到了用户体验的提高。
目前还没有看到这方面的冲突。
还看到一个简明扼要阐述区别的说明:
同步与异步是对应的,它们是线程之间的关系,两个线程之间要么是同步的,要么是异步的。
阻塞与非阻塞是对同一个线程来说的,在某个时刻,线程要么处于阻塞,要么处于非阻塞。
阻塞是使用同步机制的结果,非阻塞则是使用异步机制的结果。(不是存在同步非阻塞和异步阻塞这两种情况吗?)