同步和异步是相对于操作结果来说,会不会等待结果返回
阻塞和非阻塞是相对于线程是否被阻塞。
其实,这两者存在本质的区别,它们的修饰对象是不同的。阻塞和非阻塞是指进程访问的数据如果尚未就绪,进程是否需要等待,简单说这相当于函数内部的实现区别,也就是未就绪时是直接返回还是等待就绪。
而同步和异步是指访问数据的机制,同步一般指主动请求并等待I/O操作完毕的方式,当数据就绪后在读写的时候必须阻塞,异步则指主动请求数据后便可以继续处理其它任务,随后等待I/O操作完毕的通知,这可以使进程在数据读写时也不阻塞。
高并发的程序一般使用同步非阻塞方式而非多线程 + 同步阻塞方式
1.详细介绍
网络IO的模型大致包括下面几种
1.1同步模型(synchronous IO)
-
阻塞IO(bloking IO)
-
非阻塞IO(non-blocking IO)
-
多路复用IO(multiplexing IO)
-
信号驱动式IO(signal-driven IO)
1.2异步IO(asynchronous IO)
异步IO
网络IO的本质是socket的读取,socket在linux系统被抽象为流,IO可以理解为对流的操作。对于一次IO访问,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间,所以一般会经历两个阶段:
等待所有数据都准备好或者一直在等待数据,有数据的时候将数据拷贝到系统内核;
将内核缓存中数据拷贝到用户进程中;
对于socket流而言:
等待网络上的数据分组到达,然后被复制到内核的某个缓冲区;
把数据从内核缓冲区复制到应用进程缓冲区中;
2.1 阻塞IO
应用进程从 进行系统调用
到 复制数据报到应用进程的缓冲区完成
的整段时间内是被阻塞的
- 优点:能够及时返回数据,无延迟;方便调试;
- 缺点:需要付出等待的代价;
2.2 非阻塞IO
当一个应用进程对一个非阻塞socket循环调用 recv/recvfrom 时,则称为轮询;应用进程持续轮询内核,以查看某个操作是否就绪,这么做往往消耗大量的CPU时间。
2.2.2 优点和缺点
- 优点:相较于阻塞模型,非阻塞不用再等待任务,而是把时间花费到其它任务上,也就是这个当前线程同时处理多个任务;
- 缺点:导致任务完成的响应延迟增大了,因为每隔一段时间才去执行询问的动作,但是任务可能在两个询问动作的时间间隔内完成,这会导致整体数据吞吐量的降低。
2.3 IO多路复用
有了I/O复用,我们就可以调用 select或poll,让其阻塞在两个系统调用(1.询问数据是否准备好并且直到数据准备好才返回;2.内核是否把数据全部复制完成到用户进程)中的某一个之上
同步非阻塞方式需要用户进程不停的轮询,但是IO多路复用不需要不停的轮询,而是派别人去帮忙循环查询多个任务的完成状态,UNIX/Linux 下的 select、poll、epoll 就是干这个的
- 优点:能够同时处理多个连接,系统开销小,系统不需要创建新的额外进程或者线程,也不需要维护这些进程和线程的运行,降低了系统的维护工作量,节省了系统资源。
- 缺点:如果处理的连结数目不高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟还更大。(因为阻塞可以保证没有延迟,但是多路复用是处理先存在的数据,所以数据的顺序则不管,导致处理一个完整的任务的时间上有延迟)
网友评论