来说说epoll+线程池

阅读更多
最近在作学习epoll,也看了很多的资料,关于epoll的原理就不多说了,很简单,需要注意的是,如果仅仅的采用epoll来处理网络服务器的话,感觉性能不会提高太大,毕竟io的处理相对于epoll或者poll的检测来说,时间消耗是比较多的。这个话说得可能比较的绕口,简单说就是你每次的epoll_wait所花费的时间,相对于你得到事件后所作的read,write==花费的时间要少狠多,至少我感觉是这样子的。所以如果真的需要提升性能的话,就需要epoll+线程池,但是问题就是,这个线程池怎么做呢?很多朋友的线程池是可以自我调整的,当没有了就自动地分配。我的看法是这样子没有什么必要吧(自己对linux系统本身没有什么深的理解)。感觉仿照iocp就不错了,当然,仿照是不可能的,iocp实现很复杂的。我们模仿他的流程和机制,适当的损失些性能(只要就是事件通知机制)还是可以接受的。另外一个最大的问题就是我们还是要让操作系统来帮助我们在底层来排队,而不是自己在上层来实现排队,主要是因为处理肯定没有epol_wait产生的速度快,这样子会造成中间的缓冲队列一直增大的。所以还是留给操作系统来帮助我们排队吧。至少目前我的cobra_linux就是这样子实现的。

等有机会展示一下我的cobra_linux吧,虽然它现在还不是很完美。
 
 
#ifndef  _LC_COBRA_EPOLLER_H
#define  _LC_COBRA_EPOLLER_H



/*
* Copyright(c)2008
*
* 文件名称: Epoller
* 文件标识:
* 摘    要: Epoller是我自己封装的epoll,仿照
            Windows平台的IOCP(完成端口)来实现类似
			的一套高性能的网络底层io策略。
			Epoller实现的原理是:
			但个线程来循环我们的epoll来等待底层的网络事件
			当有事件的时候,我们就把这些事件对应的数据放入
			到我们的上层Epoller缓冲队列中,并且发出信号,通知
			阻塞在这个上面的线程可以取数据去处理。
*
* 当前版本: cobra 1.05
* 作    者: 关中刀客
* E-Mail  : [email protected]
* Blog    : http://guan-zhong-dao-ke.blog.163.com/
* 完成时间: 2008年04月28日
*/


#include "../common/Header.h"
#include 
#include 
#include 
#include 


class   EpollerEvent;
class   Epoller
{
public:
	/*
		需要监听的套接字Epoller消息
	*/
	enum EPOLLERMESSAGE
	{
		EPOLLERREAD,
		EPOLLERWRITE
	};

private:
	int                  m_epoller;   // epoller句柄
	pthread_mutex_t      m_lock;      // 中间队列的锁
	pthread_cond_t       m_cond;      // 条件变量锁
	sem_t                m_sem;       // 主轮循等待线程处理的信号量
	Queue  m_queue;  // 中间的数据结构缓冲队列 

public:
	Epoller();
	~Epoller();

public:
	/*
		初始化epoller
		queuesize : 初始化的时候我们的缓冲队列默认的大小
		number    : 处理的数目
	*/
	bool   init_epoller(size_t queuesize, size_t number);
	/*
		向epoller注册套接字需要监听事件
		sock   :   指定的套接字
		iMsg   :   注册到Epoller上的消息
		pEvent :   指定的事件数据体
	*/
	bool   register_epoller_socket_event(SOCKET sock, int iMsg, EpollerEvent* pEvent);
	/*
		改变Epoller中套接字监听的事件
		sock   :   指定的套接字
		iMsg   :   注册到Epoller上的消息
		pEvent :   指定的事件数据体
	*/
	bool   change_epoller_socket_event(SOCKET sock, int iMsg, EpollerEvent* pEvent);
	/*
		删除Epoller中套接字的所有事件
	*/
	void   delete_epoller_socket_event(SOCKET sock, int iMsg);
	/*
		向Epoller发送指定的事件
		pEvent :   指定的事件结构体
		通常情况下,我们使用这个函数控制各Epoller线程的退出
		类似于windows下的PostQueuedCompletionStatus
	*/
	void   post_event_to_epoller(EpollerEvent* pEvent);
	/*
		得到Epoller中的事件结构体数据
		pEvent :  表示得到的数据体
		一般情况下,这个函数由各Epoller线程函数调用,然后回得到指定的事件,
		然后根据事件的信息去处理
		类似于windows下的GetQueuedCompletionStatus
	*/
	bool   get_event_from_epoller(EpollerEvent* pEvent, size_t timeout);
	/*
		单独线程来循环Epoller主循环,检测套接字的事件
		timeout :  超时的时间
	*/
	int    listen_epoller_event(int timeout);
	/*
		销毁epoller
	*/
	void   destroy_epoller();
};
extern  Epoller  g_Epoller;


#endif

你可能感兴趣的:(多线程,Linux,nginx,lighttpd,Socket)