Server端处理高并发网络请求主要方法
循环:早期系统使用简单的循环选择解决方案,即循环遍历打开的网络连接的列表,判断是否有要读取的数据。这种方法既缓慢(尤其是随着连接数量增加越来越慢),又低效(因为在处理当前连接时其他连接可能正在发送请求并等待响应)。在系统循环遍历每个连接时,其他连接不得不等待。如果有 100 个连接,其中只有一个有数据,那么仍然必须处理其他 99 个连接,才能轮到真正需要处理的连接。
socket IO复用:这是对循环方法的改进,它用一个结构保存要监视的每个连接的数组,当在socket发现数据时会select/epoll调用会返回到用户空间,然后可以继续后续处理。
异步socket IO:利用现代内核中的多线程支持监听和处理连接,为每个连接启动一个新线程。这把责任直接交给操作系统,但是会在 RAM 和 CPU 方面增加相当大的开销,因为每个线程都需要自己的执行空间。另外,如果每个线程都忙于处理网络连接,线程之间的上下文切换会很频繁。这里的异步其实是不是真正的异步,模拟异步IO,将IO的操作交给专门的thread来处理而异。
异步IO主要用于direct disk IO
实践中socket IO复用已经很好地解决了高并发的问题,那么异步IO到底应用在哪里呢?一番google后发现目前大家还是公认使用IO复用解决网络编程的高并发,异步IO可以用于没有缓存的disk IO。详细看一下这个帖子What is the status of POSIX asynchronous I/O (AIO)
带cache的disk IO性能不是大问题了,kernel通过cache可以高效的解决disk 读写问题。剩下direct IO可以通过异步IO解决。linux上异步IO常见有两种实现,一种是kernel native AIO,另外是用户空间的POSIX AIO。
kernel native AIO: Kernel的原生态异步IO实现,详细可以参阅aio - POSIX asynchronous I/O overview
glibc AIO(POSIX AIO): linux用户空间异步IO的实现,其实它不是真正的异步IO,是通过启动一定数量的blocking IO线程来模拟异步IO。这种实现有不少缺点,毕竟有不少线程开销,还在改进中。
linux异步IO编程实例分析,这篇文章给了一个很好的异步IO的例子,可做参考。
参考文章
What is the status of POSIX asynchronous I/O (AIO)
Boost application performance using asynchronous I/O
linux异步IO编程实例分析
使用 libevent 和 libev 提高网络应用性能
aio - POSIX asynchronous I/O overview
Difference between POSIX AIO and libaio on Linux
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。