socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用

socket-IO模型,阻塞-非阻塞,同步-异步,IO复用

IO模型
Linux系统提供的5种IO模型:
1,阻塞IO(blocking IO)
2,非阻塞IO (nonblocking IO)
3,IO复用(select, poll, epoll) (IO multiplexing)
4,信号驱动IO (signal driven IO (SIGIO))
5,异步IO (asynchronous IO (the POSIX aio_functions))

一、阻塞-非阻塞针对服务端
阻塞:阻塞I/O;当调用了阻塞特性的函数(如 socket_read)时,会一直等待直到缓冲区有数据了才会返回,在结果返回之前,当前线程会被挂起(线程进入非可执行状态,在这个状态下,cpu不会给线程分配时间片,即线程暂停运行,代码不往下走了)。函数只有在得到结果之后才会返回,然后再返回给客户端,并且在这期间,服务端无法再接收其他的请求。当然我们可以开启多个进程来同时响应多个请求,比如php-fpm就是这样的,但是缺点很明显,系统能开启的进程数是有限的,并且进程很占用内存资源。
socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用_第1张图片
非阻塞:非阻塞I/O;当调用了阻塞特性的函数(如 socket_read)之前,可以设置socket_set_nonblock,那么socket_read将不会阻塞在那里了而是立即返回,服务端可以接受更多的请求了,效率大大提升。但是此时,函数的返回值我们需要通过其他方式来获得,然后返回给客户端。

二、同步-异步针对客户端
同步:发起网络请求–>等待服务端的响应–>处理其他事情;其实也可以理解为阻塞IO

异步:发起网络请求–>注册一个事件回调–>处理其他事情;
事件被触发–>执行回调
异步客户端提高了客户端的能力,比如浏览器发送完ajax之后就去处理其他事情了,直到服务器响应触发回调。
异步客户端要有事件循环,不断地检查有没有未处理的事件,直到全部全部处理完了才能结束。

三、IO复用
非阻塞模型下,为了获得函数返回值,可以不断反复调用IO函数(系统调用),这样会造成大量的CPU消耗,也可以使用更优的IO复用模型。
IO复用会用到内核的 select、poll、epoll 函数,这几个函数也会使进程阻塞,但是和阻塞IO所不同的是,这三个函数可以同时阻塞
多个IO操作(read,write等)。而且可以同时对多个读操作,多个写操作的IO函数进行检测(内核来完成),直到有数据可读或可写时,内核会通知应用程序,然后应用程序才真正调用IO函数。
socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用_第2张图片
socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用_第3张图片
四、信号驱动IO
不直接使用阻塞性质的IO函数,而是注册一个信号处理函数到内核,当内核发现有可读或可写时,内核调用信号处理程序,我们在信号处理程序中来实现IO操作。
socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用_第4张图片
五、异步IO
当一个异步过程调用发出后,调用者不能立刻得到结果。实际处理这个调用的部件在完成后,通过状态、通知和回调来通知调用者的输入输出操作。异步IO不会引起进程阻塞。
socket编程 - 阻塞-非阻塞,同步-异步,IO多路复用_第5张图片

你可能感兴趣的:(网络编程)