Linux下并发服务器的实现

版权声明:凡本人原创,转发请注明出处,谢谢! https://blog.csdn.net/qq_41248872/article/details/83857137

实现并发服务器的方式有多种,下面说一下我了解到的几种解决方案。

方案一:多进程并发服务器

主进程监听、accept()连接,子进程负责处理业务逻辑和流的读取。

           缺点:进程需要占用系统资源,存在硬件资源瓶颈,且调度,管理资源等系统开销较大

方案二:多线程并发服务器         

主线程监听、accept()连接,子线程负责处理业务逻辑和流的读取。      

缺点是:

  • 会频繁地创建、销毁线程,这对系统也是个不小的开销。这个问题可以用线程池来解决。线程池是预先创建一部分线程,由线程池管理器来负责调度线程,达到线程复用的效果,避免了反复创建线程带来的性能开销,节省了系统的资源。
  • 要处理同步的问题,当多个线程请求同一个资源时,需要用锁之类的手段来保证线程安全。同步处理不好会影响数据的安全性,也会拉低性能。
  • 一个线程的崩溃会导致整个进程的崩溃。

多线程的适用场景是:提高响应速度,让IO和计算相互重叠,降低延时。虽然多线程不能提高绝对性能,但是可以提高平均响应性能。

方案一、二均不适宜高并发

方案三:IO复用+多线程

利用epoll(或select、poll)监听socket,每当有请求接入时,创建一个线程accept()连接请求,并在其独立线程中与对应客户端通信。

缺点:同纯粹的多线程一致,只是将主线程的阻塞等待连接,换成了事件轮询,对单一进程来说并无区别。

方案四:单进程+多路IO复用(事件轮询)模型(select、poll、epoll) 

首先通过 socket() 来创建一个 sock 文件描述符用来监听客户端的连接,然后将已连接的socket描述符加入epoll事件监听池。

缺点:当监听池中的多个事件同时触发时,各个事件的处理并非是真正的并发进行的,而是按先后顺序循环执行的。但是epoll相对于select、poll来说,这一点已经有很大优势了,后两者当检测到事件时还需要循环检测事件描述符集,需要消耗更多的时间。

方案五:利用事件驱动库(libevent、libev、libuv等)来实现高并发

常见的事件驱动库有 libevent 库,还有作为 libevent 替代者的 libev 库。这些库会根据操作系统的特点选择最合适的事件探测接口,并且加入了信号 (signal) 等技术以支持异步响应,这使得这些库成为构建事件驱动模型的不二选择。Linux下可使用 libev 库替换 select 或 epoll 接口,实现高效稳定的服务器模型。

Libev是一个基于Reactor模式的事件库,效率较高、代码精简(4.15版本8000多行,c语言编写),是一个值得学习的轻量级事件驱动库。 它的官网(http://libev.schmorp.de/)在国内已经没法访问了。但是我们仍然可以从github上下载其源码(https://github.com/enki/libev)。

猜你喜欢

转载自blog.csdn.net/qq_41248872/article/details/83857137