一、阻塞IO(blocking)
主线程阻塞等待用户连接请求(accept阻塞)。等请求达到以后再调用(recv)系统调用接收数据,这时候又阻塞等待。
等内核将数据接受好并从内核空间拷贝到用户空间后,系统调用返回,表明数据读取完毕。
这个操作在等待IO的时候会将主线程挂起而不能执行其他操作,浪费了大量服务器性能。
二、多线程(blocking+multithread)
由于accept系统调用会对每个客户端的连接都返回一个fd,因此可以利用多线程的方法。主线程只负责accept处理连接请求。
在收到具体的请求以后 ,将客户请求的fd作为参数传给工作线程,工作线程会调用相应的线程函数来处理。
理解值观,在处理并发量不太高的时候效果可以。但是如果并发量特别高的情况下,线程的切换和调度会带来大量cpu资源的浪费(可能有大量的线程被阻塞再IO等待)并且创建线程的开销也不低。
三、非阻塞IO(no-blocking)
非阻塞IO在数据未准备好的情况下,recv等系统调用也能立即返回。而不会将整个主线程阻塞,主线程可以去处理其他操作。
然而需要主线程自行去检查每个IO队应的fd是否准备就绪(轮询select/poll或者等待系统通知epoll等)。
select/epoll的优势不是在于对于单个连接能处理得更块,而是在于能够处理更多的连接!
而传统的阻塞式的web模型,再处理连接数不是那么高的情况下,性能还是可以的。当连接数上去以后就会遇到性能瓶颈!因为大量的线程切换也是需要开销的。并且线程之间的数据同步,需要用到大量的锁等资源,还容易造成死锁等问题。
四,异步IO
asynchronous I/O Linux下的异步IO通常用于磁盘操作,不可用于网络。<