<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title></title>
    <description>小楼一夜听春雨</description>
    <link>http://guanzhongdaoke-gmail-com.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>仿mbuf机制实现自己的不定长内存池</title>
        <author>关中刀客</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://guanzhongdaoke-gmail-com.javaeye.com">关中刀客</a>&nbsp;
          链接：<a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/195769" style="color:red;">http://guanzhongdaoke-gmail-com.javaeye.com/blog/195769</a>&nbsp;
          发表时间: 2008年05月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近在考虑一个客户端底层通讯模块的实现问题，我需要做的就是把我的套接字绑定到窗口上，当套接字有事件产生，比如可读，关闭等消息的时候，直接通过窗口消息通知我，我在做一定的处理，客户端需要实现一个可伸缩的内存池来管理通讯的数据，上层在一桢中可压入许多待发送的数据，底层在一桢可接受许多服务器端的数据。所以我打算使用变长的内存池来实现，以前看过tcp/ip底层的mbuf实现机制，感觉很不错，所以这次做了一些改进，来实现我的不定长内存池策略。<br /><pre name="code" class="c++">/* 
* Copyright(c)2008 
* 
* 文件名称:  mbuf 
* 文件标识: 
* 摘    要: 仿照tcp/ip的mbuf机制实现自己的mbuf 
			pWriter只仅仅表示我们当前的写指针位置，
			而我们的iUnused只仅仅的表示我们的写指
			针位置距离我们的buff+MBUF_BUFFER_SIZE
			还有多少个可用字节数目。
			pReader只仅仅表示我们当前的读指针位置，
			而我们的iUsed也只仅仅表示我们的读指针
			位置距离我们的pWriter指针还有多少字节
			这个再次注意，我们的iUnused+iUsed不一定
			就等于buff的总体长度MBUF_BUFFER_SIZE，
			这两者之间没有任何联系
* 
* 当前版本: cobra_for_window 1.00 
* 作    者: 关中刀客 
* E-Mail  : guanzhongdaoke@gmail.com 
* Blog    : http://guan-zhong-dao-ke.blog.163.com/ 
* 完成时间: 2008年04月22日 
*/ 


#include &lt;Windows.h>


struct  mbuf
{
public:
	enum
	{
		MBUF_BUFFER_SIZE = 2048
	};

public:
	struct  mbuf*  pNext;
	struct  mbuf*  pRef;
	char*          pReader;
	char*          pWriter;
	size_t         iUsed;
	size_t         iUnused;
	char           buff[MBUF_BUFFER_SIZE];

public:
	inline  void  init_mbuf()
	{
		pNext    =  NULL;
		pRef     =  this;
		pReader  =  buff;
		pWriter  =  buff;
		iUsed    =  0;
		iUnused  =  MBUF_BUFFER_SIZE;
		
		memset(buff, 0, sizeof(buff));
	}
};


struct  mbuf;
class   mbufpool
{
private:
	struct  mbuf*  m_pBegin;
	struct  mbuf*  m_pEnd;
	struct  mbuf*  m_pFinish;
	size_t         m_iBytes;

public:
	mbufpool();
	~mbufpool();

public:
	/*
		得到数据开始的节点
	*/
	mbuf*    begin();
	/*
		得到数据结尾的节点
	*/
	mbuf*    end();
	/*
		得到当前mbufpool中所存字节的总数
	*/
	size_t   get_bytes_number();
	/*
		设计当前mbufpool中所存字节的总数
	*/
	void     set_bytes_number(size_t iBytes);
	/*
		增加制定数目的mbuf节点
	*/
	void     resize(size_t iNum);
	/*
		m_pBegin向后移动
	*/
	void     next();
	/*
		压入一些节点
	*/
	void     push_node(mbuf* pNode);
	/*
		压入一定长度的数据
	*/
	void     push_data(const char* pData, size_t iNum);
	/*
		得到一定数目的字节
	*/
	bool     pop_data(char* pData, size_t iNum);
	/*
		销毁mbufpool
	*/
	void     destroy();

private:
	/*
		从系统中分配节点
	*/
	void     malloc_mbuf_from_system();
};



class cobra_socket
{
private:
	SOCKET    m_sock;
	mbufpool  m_recvpool;
	mbufpool  m_sendpool;

public:
	cobra_socket();
	~cobra_socket();

public:
	void    init_cobra_socket(size_t iRecvpollSize, size_t iSendPoolSize);
	bool    create_socket();
	bool    connect_to_server(const char* pIP, u_short port);
	bool    bind_to_window(HWND hWnd, int wMsg, int iMsg);
	bool    logic_recv(char* pBuff, size_t iNum);
	void    logic_send(const char* pBuff, size_t iNum);
	bool    start_recv();
	bool    start_send();
	void    close_socket();
	void    destroy_cobra_socket();
};</pre>感觉这个方法挺不错的，当然，如果各位朋友有更好的建议或者意见的话，欢迎和我联系^__^
          <br/>
          <span style="color:red;">
            <a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/195769#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 22 May 2008 18:26:24 +0800</pubDate>
        <link>http://guanzhongdaoke-gmail-com.javaeye.com/blog/195769</link>
        <guid>http://guanzhongdaoke-gmail-com.javaeye.com/blog/195769</guid>
      </item>
      <item>
        <title>仿照linux定时器实现自己的定时器管理器策略</title>
        <author>关中刀客</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://guanzhongdaoke-gmail-com.javaeye.com">关中刀客</a>&nbsp;
          链接：<a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/193284" style="color:red;">http://guanzhongdaoke-gmail-com.javaeye.com/blog/193284</a>&nbsp;
          发表时间: 2008年05月15日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: medium">以前在网上看到了linux系统中定时器实现的策略，感觉很不错，虽然没有使用什么RBTree==的优秀算法，就仅仅使用数组，链表来实现的，但是性能个方面没有什么问题。感触"简单就是美"阿！最近自己需要一个定时器，所以就仿照这个来实现自己的定时器管理器，并且作了进一步的优化和改进，并且还需要考虑多线程中串行话的问题。<br />来说说自己的实现策略吧！<br />我使用了两个缓冲区，一级缓冲区是一个定长的数组，存放在固定时间内将触发的所有事件，二级缓冲区时一个链表，存放时间比较长才出发的事件，然后我的主循环就只轮训一级缓冲区，每次处理固定位置的所有事件，当到达数组末尾的时候，说明所有的事件已经处理完毕，这个时候，需要从二级缓冲区中找到下一个数组长度时间内需要处理的事件，插入到一级缓冲区中。整体的逻辑算是很清楚了，但是看目前的代码，还是比较的2（^_^)，关键处理很多的指针的指针。<br />如果您有更好的建议和策略，欢迎与我联系<br /><span style="color: red">E_mail: guanzhongdaoke@gmail.com<br />Blog:   guan-zhong-dao-ke.blog.163.com</span><br />                                      关中刀客<br />                                            2008-05-15</span>
          <br/>
          <span style="color:red;">
            <a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/193284#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 15 May 2008 14:44:43 +0800</pubDate>
        <link>http://guanzhongdaoke-gmail-com.javaeye.com/blog/193284</link>
        <guid>http://guanzhongdaoke-gmail-com.javaeye.com/blog/193284</guid>
      </item>
      <item>
        <title>来说说epoll+线程池</title>
        <author>关中刀客</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://guanzhongdaoke-gmail-com.javaeye.com">关中刀客</a>&nbsp;
          链接：<a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/189005" style="color:red;">http://guanzhongdaoke-gmail-com.javaeye.com/blog/189005</a>&nbsp;
          发表时间: 2008年05月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          最近在作学习epoll,也看了很多的资料，关于epoll的原理就不多说了，很简单，需要注意的是，如果仅仅的采用epoll来处理网络服务器的话，感觉性能不会提高太大，毕竟io的处理相对于epoll或者poll的检测来说，时间消耗是比较多的。这个话说得可能比较的绕口，简单说就是你每次的epoll_wait所花费的时间，相对于你得到事件后所作的read,write==花费的时间要少狠多，至少我感觉是这样子的。所以如果真的需要提升性能的话，就需要epoll+线程池，但是问题就是，这个线程池怎么做呢？很多朋友的线程池是可以自我调整的，当没有了就自动地分配。我的看法是这样子没有什么必要吧（自己对linux系统本身没有什么深的理解）。感觉仿照iocp就不错了，当然，仿照是不可能的，iocp实现很复杂的。我们模仿他的流程和机制，适当的损失些性能(只要就是事件通知机制)还是可以接受的。另外一个最大的问题就是我们还是要让操作系统来帮助我们在底层来排队，而不是自己在上层来实现排队，主要是因为处理肯定没有epol_wait产生的速度快，这样子会造成中间的缓冲队列一直增大的。所以还是留给操作系统来帮助我们排队吧。至少目前我的cobra_linux就是这样子实现的。<br /><br />等有机会展示一下我的cobra_linux吧，虽然它现在还不是很完美。<br /><pre name="code" class="c++"></pre><br /><pre name="code" class="java">#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  : guanzhongdaoke@gmail.com
* Blog    : http://guan-zhong-dao-ke.blog.163.com/
* 完成时间: 2008年04月28日
*/


#include "../common/Header.h"
#include &lt;sys/epoll.h>
#include &lt;sys/socket.h>
#include &lt;pthread.h>
#include &lt;semaphore.h>


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&lt;EpollerEvent, EmptyLock>  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</pre>
          <br/>
          <span style="color:red;">
            <a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/189005#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 03 May 2008 01:18:14 +0800</pubDate>
        <link>http://guanzhongdaoke-gmail-com.javaeye.com/blog/189005</link>
        <guid>http://guanzhongdaoke-gmail-com.javaeye.com/blog/189005</guid>
      </item>
      <item>
        <title>祝贺自己的blog开张</title>
        <author>关中刀客</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://guanzhongdaoke-gmail-com.javaeye.com">关中刀客</a>&nbsp;
          链接：<a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/189004" style="color:red;">http://guanzhongdaoke-gmail-com.javaeye.com/blog/189004</a>&nbsp;
          发表时间: 2008年05月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          祝贺自己的javaEye博客开张<br />以后就再这个地方不断的积累，不断地成长<br />.....................
          <br/>
          <span style="color:red;">
            <a href="http://guanzhongdaoke-gmail-com.javaeye.com/blog/189004#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 03 May 2008 01:16:02 +0800</pubDate>
        <link>http://guanzhongdaoke-gmail-com.javaeye.com/blog/189004</link>
        <guid>http://guanzhongdaoke-gmail-com.javaeye.com/blog/189004</guid>
      </item>
  </channel>
</rss>