赞
踩
用libevent进行网络编程(fork,thread,event_based)
1、我们知道处理多用户时有几种方法:
(1)、fork():一个新的connection()进来,用fork()产生一个process处理。
(2)、pthread_create()产生一个新的thread处理。
(3)、把新的connection丢入Event-based Array,然后由Main Process以Nonblocking方式处理所有IO。
2、这三种方法当然也有自个的缺点:
(1)、用fork()问题在于一个Connection进来的成本太高。(子进程要获得父进程的的数据控件,堆,栈。父子进程之间并不共享这些存储空间)。
(2)、用多线程的问题在于Thread-safe与Deadlock问题难以解决,另外由Memory-leak问题要处理。
(3)、用Event-based的方式在于实现上不好写,尤其是要注意到事件产生是必须要Nonblocking,于是会需要作Buffering的问题。多线程所会遇到的Memory-leak问题在这儿会更严重。而再多CPU的系统上没有办法使用到所有的CPU资源。
3、当然,针对前面两项由自个的解决方法:
(1)以poll的方式解决:当一个process处理完一个Connection后,不直接死掉,而是继续回到accept()的状态继续处理,但这样会遇到Memory-leak的问题,于是采用这种方式的人通常会加上“处理过N个Connection后死掉,由Parent process再fork()新的。”最有名的例子是Apache1.3。
(2)Thread-safe的问题可以透过自己撰写,或是寻找其他的Thread-safe库直接使用。Memory-leak的问题可以试着透过Garbage Connection Libray分析出来。Apache2.0的Thread MPM就是使用这个模式的。
4、然而,目前高效的server都偏好采用event-based,一方面是没有Create Process/Thread所造成的开销,令一方面是不需要透过Memory或是Mutex在不同的Process/Thread之间交换。而event-based在实际上的几个复杂的地方在于:
select()与poll()的效率过慢,造成每次都要判断“由那些event发生”,这件事的成本很高,这个BSD上的改进为kqueue()、linux上的改进为epoll(),这两个函数都不是标准,于是不同的平台上需要做修改。因为Nonblocking,所以再write()或者send()时不能一次完成,这就需要自己Buffering。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。