<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>iunknown</title>
    <description></description>
    <link>http://iunknown.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>在 SPServer 中集成 IOCP 和 SSL</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/206501" style="color:red;">http://iunknown.javaeye.com/blog/206501</a>&nbsp;
          发表时间: 2008年06月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          打算把 Windows 的 SSPI 集成到 SPServer/IOCP 的框架中，这样可以减少 SPServer 对第三方库的依赖。但是看了一下 SSPI 之后，望而生畏啊。对比 openssl ，SSPI 接口相当于与其中的 BIO 接口，并且比 BIO 接口更难用。找了几个例子来看，每个的代码基本上都是又长又难看，太多的错误判断了。最后还是直接在 windows 上用 openssl 算了。看了 openssl 在 windows 下的编译步骤，决定都是放弃自己编译的想法。在网上找了个已经编译好的版本，然后把原来在 linux 下的 openssl 插件在 vc 下编译，经过一轮调试，看起来能跑了。<br /><br />gnutls 也有已经编译好的 windows 版本。<br /><br />gnutls for windows<br />http://josefsson.org/gnutls4win/<br /><br />openssl for windows<br />http://www.slproweb.com/products/Win32OpenSSL.html
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/206501#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 20 Jun 2008 22:27:48 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/206501</link>
        <guid>http://iunknown.javaeye.com/blog/206501</guid>
      </item>
      <item>
        <title>[zz]VS2008在WindowsXP下调试程序出R6034错误</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/203131" style="color:red;">http://iunknown.javaeye.com/blog/203131</a>&nbsp;
          发表时间: 2008年06月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          原文：http://ks.cn.yahoo.com/question/1308031705287.html<br /><br />在此之前，参考了很多关于R6034错误的网页，主要是考虑manifest：<br />（1）磁盘系统是fat32格式的：FAT32的时间精度不够,所以linker在生成文件的时候会出错，如果是ntfs的就没有问题.VS2005项目设置里面在清单工具（Manifest Tool）下面有一个选项"使用FAT32解决办法"(Use FAT32 work around)是专门解决这个问题的.对于FAT32的磁盘，需要选择"Yes"，默认是"No". <br />(2)Visual Studio 2005用向导生成的项目，在运行时可能会遇到找不到MFC80UD.dll的问题。这个问题可能是Manifest 引起的，因此我们可以通过修改项目属性(properties)->清单工具(property pages)->链接(linker)-->manifest file -->Allow Isolation，把“嵌入清单”选“否”，.然后编译、链接、运行即可。Visual Studio 2005用向导生成的项目，在运行时可能会遇到找不到MFC80UD.dll的问题。这个问题可能是Manifest 引起的，因此我们可以通过修改项目属性->清单工具->输入输出，把“嵌入清单（Embed Manifest）”选“否”，.然后编译、链接、运行即可。 <br />(3)有人提示，在项目属性里，mfc的使用应该设置为静态链接。但我改成静态后，会有很多错误，于是放弃。<br />（4）问了一个论坛上的网友，他说可能和Microsoft C++ Runtime Library有关系。<br />除此之外，一个参考文献上说的解决方法是：将Linker->Manifest File ->Allow Isolation：Do not Allow Side by Side isolation，则无论在Debug和Release条件，都出现如下：This application has failed to start because MSVCR80D.dll was not found. Re-installing the application may fix the problem." 关于这个问题，有篇博客文章上说： VS2005在FAT32分区的介质上对于Win32程序编译的一些注意问题描述：大部分的vs.net 2005的用户在新建“win32项目－windows应用程序”的时候，新建的工程都通不过去，出现如下提示：Solution to “MSVCR80D.dll not found”<br />“没有找到MSVCR80D.dll，因此这个应用程序未能启动。重新安装应用程序可能会修复此问题。”<br /><br />问题所在：由于vs.net 2005 采用了一种新的DLL方案，搞成一个exe还要配有一个manifest文件（一般在嵌入文件里了，所以看不到
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/203131#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 13 Jun 2008 22:36:57 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/203131</link>
        <guid>http://iunknown.javaeye.com/blog/203131</guid>
      </item>
      <item>
        <title>Reasons for threading</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/202284" style="color:red;">http://iunknown.javaeye.com/blog/202284</a>&nbsp;
          发表时间: 2008年06月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.sagemath.org:9001/GlennTarbox/DsageNg" target="_blank">http://www.sagemath.org:9001/GlennTarbox/DsageNg</a><br /><br />There are 2 reasons for threading at high levels:<br />1. Blocking on code which you can't change<br />2. Can't figure out how to make it asynchronous
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/202284#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 11 Jun 2008 20:49:00 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/202284</link>
        <guid>http://iunknown.javaeye.com/blog/202284</guid>
      </item>
      <item>
        <title>MySQL 6.0, Libevent</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/200803" style="color:red;">http://iunknown.javaeye.com/blog/200803</a>&nbsp;
          发表时间: 2008年06月06日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://krow.livejournal.com/2008/01/01/" target="_blank">http://krow.livejournal.com/2008/01/01/</a><br /><br />MySQL 6.0, Libevent<br />Jan. 1st, 2008 | 11:30 am<br /><br />Currently in the 6.0 tree we have support for Libevent. This is one of those things I've been wanting to see<br />us do for years and it was finally completed a few weeks ago by Damien<br />Katz (aka CouchDB) with some help from Dmitri Lenev.<br /><br />So what does this do? MySQL uses a 1:1 ratio for connections and<br />threads. Libevent allows us to pull threads into pools and use them<br />for connections. This is pretty awesome for 8way machines since<br />partially solves thread contention issues. Below is an example of<br />MyISAM doing large number of inserts with the number of users doing<br />inserts increasing (1-300 users). The graph shows the time taken for<br />each test run. Similar numbers show up when you run benchmarks with<br />Innodb (leave concurrent set to zero as you should normally do, this<br />will allow libevent to more effectively control the thread usage).<br />The green line shows the test running with 20 threads, while the blue<br />is unlimited. I do not have good rules of thumb yet for thread number<br />vs processors. The machine I used for this test is an 8way that I have<br />on loan from Intel. I will work out a similar test for Solaris once I<br />can get the code to compile there.
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/200803#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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>Fri, 06 Jun 2008 10:19:13 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/200803</link>
        <guid>http://iunknown.javaeye.com/blog/200803</guid>
      </item>
      <item>
        <title>集成 IOCP 到 Libevent</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/199143" style="color:red;">http://iunknown.javaeye.com/blog/199143</a>&nbsp;
          发表时间: 2008年06月01日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          集成 IOCP 到 Libevent<br /><br />完整的代码在<br /><a href="http://spserver.googlecode.com/files/libevent-1.4.4-iocp-3.zip" target="_blank">http://spserver.googlecode.com/files/libevent-1.4.4-iocp-3.zip</a><br /><br />IOCP 是真正的异步 IO ，Libevent 提供的是一个 event-driven 的接口。<br /><br />异步 IO 和 event-driven 的区别：<br />1.对于 event-driven，需要等待内核通知我们去启动一个IO操作，然后直接得到IO操作的结果<br />2.对于异步IO，我们可以随时无阻塞地启动 IO，然后由内核通知我们 IO 操作何时完成<br /><br />要把 IOCP 集成到 libevent ，基本的思路是用 IOCP 模拟 event-driven 接口。<br />在 IOCP 中有一个特性，刚好可以用来模拟 event-driven 的接口：zero byte buffer recv/send。<br /><br />当我们发起 WSARecv，WSASend 的时候，需要用 WSABUF 传递一个 buffer 进去。<br />如果我们把这个 buffer 设置为 zero byte ，那么当 socket 可读，或者可写的时候，<br />通过 GQCS 同样可以得到结果。这样就等于是模拟了 event-driven 的接口。<br /><br />另一方面，Windows 的 WSAEventSelect 函数提供了一个 event-driven 的 accept 功能。<br /><br /><pre name="code" class="java">
...
WSAEventSelect( listenFd, hEvent, FD_ACCEPT );
...
</pre><br /><br />问题在于如何把 IOCP 和 WSAEventSelect 集成起来。<br /><br />通过查看 WSARecv，WSASend 的接口，可以注意到这两个接口都需要提供一个 OVERLAPPED 的结构体。<br />在这个结构体里有一个 hEvent 的成员。如果设置了这个 hEvent 参数，那么当这个 IO 请求完成的时候，<br />hEvent 将会被 signal 。详细信息可以参考下面这个 URL ：<br /><br />http://msdn.microsoft.com/en-us/library/ms742203(VS.85).aspx<br /><div class="quote_title">引用</div><div class="quote_div">If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or WSAGetOverlappedResult to wait or poll on the event object.</div><br /><br />这样看起来可以通过 WSAWaitForMultipleEvents 来集成 IOCP 和 WSAEventSelect 。<br />1.用 WSAEventSelect 来处理 accept event<br />2.用 IOCP 来处理 recv/send event ，发起 recv/send 请求的时候，设置 OVERLAPPED 的 hEvent 参数<br />3.把 WSAEventSelect 的 hEvent 和 IOCP 的 hEvent 收集起来，用 WSAWaitForMultipleEvents 统一处理<br /><br />需要注意的时候，上述的第二步中，不需要为每个 recv/send 请求生成一个新的 hEvent，<br />而是所有的 recv/send 共用一个 hEvent 就行了。<br /><br />在下面这个 URL 中提到，对于一个 hEvent 如果已经是 signal ，再次 signal ，不会有副作用。<br />http://msdn.microsoft.com/en-us/library/ms686211(VS.85).aspx<br /><div class="quote_title">引用</div><div class="quote_div">Setting an event that is already set has no effect.</div><br /><br /><br />用代码来描述上面的这个思路，大概是下面这样。<br />首先创建 64 个 hEvent ，其中的 objects[0] 就用于 IOCP 中所有的 IO 操作。<br />其他剩余的 63 个 hEvent ，就可以用于 accept event 。<br />程序首先调用 WSAWaitForMultipleEvents 来等待 event 发生。<br />如果发现是 objects[0] 有事件，那么是 IOCP 的 IO 操作已经有完成的，就调用 GQCS 来处理。<br />如果发现是其他的 objects 有事件，那么就是有 accept event 发生。<br /><br /><pre name="code" class="java">
/* objects[0] for iocp operations, object[1..63] for accept */
HANDLE objects[64];
struct event * accepts[64];
 
struct win32iocp_event event1;
event1.overlapped.hEvent = objects[0];
WSARecv( ..., &event1.overlapped, ... );
....
 
struct win32iocp_event event2;
event2.overlapped.hEvent = objects[0];
WSASend( ..., &event2.overlapped, ... );
...
 
WSAEventSelect( ev1->ev_fd, objects[1], FD_ACCEPT );
accepts[1] = ev1;
...
 
WSAEventSelect( ev2->ev_fd, objects[2], FD_ACCEPT );
accepts[2] = ev2;
...
 
int index = WSAWaitForMultipleEvents( 64, objects, FALSE, timeout, FALSE );
index = index - WSA_WAIT_EVENT_0;
 
if( index > 0 ) {
 struct event * event = win32iocp_op->accepts[index];
 event_active (event, EV_READ | EV_ACCEPT, 1);
}
 
if( index == 0 ) {
 for( ; ; ) {
  GetQueuedCompletionPort( ...... );
 }
}
 
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/199143#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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>Sun, 01 Jun 2008 14:36:20 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/199143</link>
        <guid>http://iunknown.javaeye.com/blog/199143</guid>
      </item>
      <item>
        <title>[zz]Emulate event driven i/o by IOCP</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/198169" style="color:red;">http://iunknown.javaeye.com/blog/198169</a>&nbsp;
          发表时间: 2008年05月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://mail-archives.apache.org/mod_mbox/apr-dev/200504.mbox/%3C4265083D.2020009@wstoddard.com%3E" target="_blank">原文</a><br /><br />It may be possible to use IOCompletionPorts on Windows to implement apr_pollset_*.  IOCPs<br />aare very scalable <br />but moving to IOCPs will require a complete rewrite of the apr_socket implementation on Windows.<br />And there is <br />the small matter of a simple technical issue that needs to be investigated...<br /><br />IOCPs support true async network i/o. BSD KQ, Solaris /dev/poll, epoll et. al. are not async,<br />they are event <br />driven i/o models. When you issue an async read on Windows, the kernel will start filling<br />your i/o buffer as <br />soon as data is available. With event driven i/o, the kernel tells you when you can do a read()<br />and expect to <br />receive data. See the difference? Your buffer management strategy will be completely different<br />between async <br />i/o and event driven i/o and I am not sure how APR (or applications that use APR) can be made<br />to support both <br />cleanly. So back to the small technial issue that needs to be investigated...<br /><br />I believe (but have not verified) that it is possible to use IOCPs to emulate event-driven<br />network i/o. When <br />you make read or write calls for which you want to emulate event driven i/o, pass in a 0 length<br />buffer (ie, <br />you can manage your i/o buffers using event driven semantics).  So if you issue a read passing<br />in a 0 length <br />buffer, your IOCP will get notified when there is data to read. I think :-)<br /><br />Assuming the above technique works reliably, we still need to figure out how to optimize the<br />i/o. In general, <br />if there is data to read or write, synchronous calls are more efficient (if there is data<br />to read, then just <br />read it rather than telling the kernel to tell you via a notification method that there is<br />data to read. How <br />do you do that on Windows if you want to emulate event driven i/o?
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/198169#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 29 May 2008 11:21:02 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/198169</link>
        <guid>http://iunknown.javaeye.com/blog/198169</guid>
      </item>
      <item>
        <title>用完成端口（IOCP）实现一个简单的服务器框架</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/196609" style="color:red;">http://iunknown.javaeye.com/blog/196609</a>&nbsp;
          发表时间: 2008年05月25日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          IOCP 对于高并发的应用程序提供了良好的支持，使得开发高并发的应用程序的难度降低了很多。<br />IOCP 作为系统底层的 API ，保持了尽可能高的灵活性，对于很多复杂的情况，IOCP 也一样适用。<br />这种灵活性是一种双刃剑，对于复杂的情况，没有这种灵活性就没有办法完成工作。<br />但是对于简单的情况，这种灵活性就带来了额外的负担。<br /> <br />这里将要提到的这个服务器框架（spserver/iocp版），主要是针对以下的这几种典型的应用程序<br />1.echo/http 类型，server 不需要在多个 client 之间转发消息<br />2.chatroom 类型，server 在多个 client 之间转发消息<br /> <br />在使用 IOCP 来实现这两类应用程序的时候，会遇到一些共同的问题<br />1.当连接断开的时候，在 server 端为这个连接分配的资源如何妥善地进行释放<br />2.如何为每一个 IO 操作设定一个超时时间，以使得 server 能够更好地了解每个连接的当前情况<br /> <br />spserver 通过使用 hash 表的方式来解决资源释放的问题，具体的讨论可以参考<br /><a href="http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e" target="_blank">http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e</a><br /> <br />spserver 通过使用类似 libevent 的 min-heap 来解决 IO 操作超时的问题，具体可以参考<br /><a href="http://groups.google.com/group/dev4server/browse_thread/thread/0978e2e1a5c8e2fb" target="_blank">http://groups.google.com/group/dev4server/browse_thread/thread/0978e2e1a5c8e2fb</a><br /> <br />在上一个版本（0.9）中，spserver 在 windows 平台还是基于 libevent + pthread-win32 来实现的。<br />最新版本（0.9.1），在 windows 平台改成使用 IOCP + Windows Thread 来重新实现。<br />最新版本在 Windows 平台已经不再需要依赖第三方的库了。<br /> <br />主页和下载地址<br /><a href="http://code.google.com/p/spserver/" target="_blank">http://code.google.com/p/spserver/</a><br /><a href="http://spserver.googlecode.com/files/spserver-0.9.1.src.tar.gz" target="_blank">http://spserver.googlecode.com/files/spserver-0.9.1.src.tar.gz</a><br /><br />关于 spserver 更多的介绍，请参考<br /><a href="http://iunknown.javaeye.com/blog/59804" target="_blank">http://iunknown.javaeye.com/blog/59804</a>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/196609#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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>Sun, 25 May 2008 00:01:28 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/196609</link>
        <guid>http://iunknown.javaeye.com/blog/196609</guid>
      </item>
      <item>
        <title>mysql 6 网络层 IO 的设计</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/193973" style="color:red;">http://iunknown.javaeye.com/blog/193973</a>&nbsp;
          发表时间: 2008年05月17日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          mysql 6 中关于网络层 IO 的设计，在下面这个链接中讲了大体的思路<br /><a href="http://forge.mysql.com/worklog/task.php?id=441" target="_blank">http://forge.mysql.com/worklog/task.php?id=441</a><br /><br />首先提到了目前的设计，one_thread_per_connect 模型。<br /><div class="quote_title">引用</div><div class="quote_div"><br />......<br />- A new thread is created to serve this socket. (Actually, with a <br />thread cache, it might reuse an existing thtread.)<br />......<br /><br />In short: The above design does not scale. <br /></div><br /><br />新的设计看起来是一个 半同步半异步 模型，使用 libevent 来管理网络层的 IO 。<br /><br /><div class="quote_title">引用</div><div class="quote_div"><br />- One (main) thread loops over a select/poll where one (or more) of <br />the sockets is the one for new connections. <br />- If a new connection was made, accept it and add the new socket to <br />the set of sockets. <br />- Input on the other sockets is read and the incomming messages <br />each assembled.<br />- Each complete request is passed on to a pthread condition <br />variable protected queue. <br /> <br />- A (fixed) pool of service threads waits for new requests on the <br />queue. <br />- When a new requests is received in the queue, one of the threads <br />will grab it and handle it, and then return to grab new requests <br />from the queue. <br /></div><br /><br />有一个 main 线程负责处理 IO ，有一个线程池负责处理具体的 SQL 事务。<br /><div class="quote_title">引用</div><div class="quote_div"><br />- It's possible to have more than one "main" thread doing the I/O, <br />if the I/O is believed to be a bottleneck in large, high-load <br />installations. However, this also causes some problems, with load <br />balancing among other things. A first step should be limited to <br />just having one main thread. <br /></div><br /><br />对比 memcached ，同样在 多线程 环境下使用 libevent ，但是两者还是有不同。<br />memcached 的具体事务可以直接在 event_loop 线程中进行处理，但是 mysql 的就不行。<br />所以 mysql 还需要有一个工作者线程池。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/193973#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 17 May 2008 22:24:25 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/193973</link>
        <guid>http://iunknown.javaeye.com/blog/193973</guid>
      </item>
      <item>
        <title>IOCP 的资源释放问题</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/191944" style="color:red;">http://iunknown.javaeye.com/blog/191944</a>&nbsp;
          发表时间: 2008年05月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在参考了一些资料，并且尝试了几次之后，也逐渐想到了一个用来安全释放 IOCP 资源的办法。<br /><a href="http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e" target="_blank">http://groups.google.com/group/dev4server/browse_thread/thread/29a91064931a628e</a><br /><br />接着发现有人已经把这种方案描述的很清楚了<br /><a href="http://blog.codingnow.com/2007/07/robust.html#comment-12142" target="_blank">http://blog.codingnow.com/2007/07/robust.html#comment-12142</a><br /><br />对大家的讨论不置可否，但是使用ID代替指针确实在某些方面是有益处的。<br />而某些时候我们无法使用智能指针。举个例子，完成端口中<br /><br /><pre name="code" class="java">
GetQueuedCompletionStatus(
*pTHIS,
&dwNumberBytes,
(PULONG_PTR)&lpKey,
&lpEvent,
INFINITE
);
</pre><br /><br />其中的lpKey是一个非常关键的变量，我们一般把它置为一个对象的指针。这样我们就可以通过这个指针去访问该对象。<br /><br />但是事实上很多时候这个指针的生命周期是不固定的，而由于其传入的是PULONG_PTR类型的值，我们又不能直接使用智能指针。要么就要繁琐的执行addref 和 release 这样的操作而完全丢失智能指针的优越性。<br /><br />可是，如果这里传入的是一个ID或者HANDLE，为其对象的访问增加一层间接性。那么我们就可以预防非法的指针访问，从而达到安全的生命周期管理。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/191944#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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>Sun, 11 May 2008 15:52:03 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/191944</link>
        <guid>http://iunknown.javaeye.com/blog/191944</guid>
      </item>
      <item>
        <title>IOCP 摘要</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/187241" style="color:red;">http://iunknown.javaeye.com/blog/187241</a>&nbsp;
          发表时间: 2008年04月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          windows 高级编程指南 第三版 Page 601<br /><br />IIS 使用了一个相当复杂的算法来管理它的线程池。IIS 创建的最大线程数目是动态的。当IIS初始化时，对每个 CPU ，它最多允许创建 10 个线程。不过，根据客户请求，这一最大值可能会增加。IIS 设的最大值是计算机上的 RAM 的 M 字节数的两倍。<br /><br />当一个客户请求要执行一个 ISAPI DLL 中的代码时，IIS 增大了池中的最大线程数目。当 ISAPI 函数返回时，IIS 减少了该值。这是因为 IIS 不知道 ISAPI DLL 函数要做什么事情。如果函数进入了一个无限循环，IIS 就失去了一个线程。所以 IIS 就增大了池中的最大线程数目。<br /><br /><br />Page 598<br />GetQueuedCompletionStatus返回可能有多种原因，如果传递无效完成端口句柄，函数返回False，GetLastError返回一个错误(ERROR_INVALID_HANDLE),如果超时，返回False, GetLastError返回WAIT_TIMEOUT, i/o完成队列删除一项，该表项是一个成功完成的I/O请求，则返回True。<br /><br />当从 I/O 完成队列中删除一项时，有 lpdwNumberOfBytesTransferred, lpdwCompletionKey 和 lpOverlapped 参数指向的变量被设为反映该表项的信息。如果删除的表项代表一个成功完成的 I/O 请求，GQCS 返回 TRUE 。不过，如果删除的表项代表一个失败的 I/O 请求，GQCS 将返回 FALSE，调用 GetLastError 返回失败的原因。<br /><br />可以通过检查 lpOverlapped 变量的值来判断 GQCS 失败的原因，如下面的代码所示：<br /><br /><pre name="code" class="java">

DWORD dwNumberOfBytesTransferred, dwCompletionKey;

LPOVERLAPPED lpOverlapped;

BOOL fOk = GQCS( ..., &dwNumberOfBytesTransferred, &dwCompletionKey,
        &lpOverlapped, 1000 );

DWORD dwError = GetLastError();

if( fOk ) {
    // process a successfully completed I/O request.
} else {
    if( lpOverlapped != NULL ) {
        // process a failed completed I/O request.
        // dwError contains the reason for failure
    } else {
        if( dwError == WAIT_TIMEOUT ) {
            // Time-out while waiting for completed I/O entry
        } else {
            // Bad call to GQCS
            // dwError contains the reason for the bad call
        }
    }
}
</pre><br /><br />http://itamarst.org/writings/win32sockets.html<br /><br /><div class="quote_title">引用</div><div class="quote_div"><br />Differences in partial writes to TCP sockets (contributed by James Knight).<br />    In Unix, socket.send(buf) will buffer as much of buf as it has space for, and then return how much it accepted. This could be 0 or up to something around 128K. If you send some data and then some more, it will append to the previous buffer.<br /><br />    In Windows, socket.send(buf) will either accept the entire buffer or raise ENOBUFS. Testing indicates that it will internally buffer any amount up to 50MB (this seems to be the total for either the process or the OS, I'm not sure). However, it will not incrementally accept more data to append to a socket's buffer until the big buffer has been completely emptied (seemingly down to the SO_SNDBUF length, which is 8192), but rather raises WSAEWOULDBLOCK instead.<br /><br /></div><br /><br />&lt;Network Programming for Microsoft Windows, Second Edition><br /><br /><div class="quote_title">引用</div><div class="quote_div"><br />Maximizing Connections<br />Maximizing the number of concurrent client connections is the more difficult of the two strategies. Handling the I/O on each connection becomes difficult. A server cannot simply post one or more sends or receives on each connection because the amount of memory (both in terms of locked pages and non-paged pool) is great. In this scenario, the server is interested in handling many connections at the expense of throughput on each connection. An example of this would be an instant messenger server. The server would handle many thousands of connections but would need to send or receive only a small number of bytes at a time.<br /><br />For this strategy, the server does not necessarily want to post an overlapped receive on each connection because this would involve locking many pages for each of the receive buffers. Instead, the server can post an overlapped zero-byte receive. Once the receive completes, the server would perform a non-blocking receive until WSAEWOUDLBLOCK is returned. This allows the server to immediately receive all buffered data received on that connection. Because this model is geared toward clients that send data intermittently, it minimizes the number of locked pages but still allows processing of data on each connection.<br /></div>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/187241#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 27 Apr 2008 11:05:34 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/187241</link>
        <guid>http://iunknown.javaeye.com/blog/187241</guid>
      </item>
      <item>
        <title>[zz] 川人陈春先</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/184612" style="color:red;">http://iunknown.javaeye.com/blog/184612</a>&nbsp;
          发表时间: 2008年04月20日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          作者：吴晓波<br /><br />    2004年8月9日，陈春先去世，两天前，他刚刚过了70岁的生日。即便是中关村的人，也没有几个还记得他的名字了，“遗忘”是这部中国企业史最重要的特征之一。<br /><br />    1980年10月，中国最顶尖的核聚变专家、46岁的中国科学院物理所研究员陈春先从美国考察回来，这已经是他两年里第三次访问美国了，这几次出国让他印象最深的倒还不是美国同行的学术进步，而是那个国家在技术产业化上的扩散能力。他每次都会去两个地方，一是西部的硅谷，还有就是东部的波士顿“128号公路”。走在那两条房屋低矮、丛木葱绿的狭长地带，他突然萌生了一股从来没有过的激情。陈春先是当时国内最有前途的新生代科学家，在1978年，中科院评聘了改革开放后的第一批教授级研究员，一共只有10人，陈春先与后来成为“时代偶像”的数学家陈景润一起在榜。而此次的硅谷之旅却彻底地改变了他的人生。<br /><br />    回国后，他向上级写报告提出，中国应该建设自己的“硅谷”，他写道，“美国高速度发展的原因在于技术转化为产品特别快，科学家和工程师有一种强烈的创业精神，总是急于把自己的发明、专有技术和知识变成产品，自己去借钱，合股开工厂。”在他的方案中，甚至已经圈定了“中国硅谷”的地点，那就是他工作所在的中关村。<br /><br />    中关村真是北京城北面的一个小村庄的名字。1949年以前，这里是一个有70户住家、276口人的自然小村，周边的坟地占了土地的30%多。1952年，中国科学院定址于此，再一年，燕京大学与北京大学合并，又在这个小村的北部形成一个教研院区。日后，中关村一带先后建起了中科院的几个重点研究所和大面积的员工宿舍，成为科研人员聚集度很高的一个区域。陈春先在报告中说，“我们在中关村工作了20多年，这里的人才密度绝不比旧金山和波士顿地区低，素质也并不差，我总觉得有很大的潜力没有挖出来。”<br /><br />    如果仅仅是这样写写报告、讲讲话，倒也罢了，陈春先却是想真的把自己当成试验品全部地投进去。在回国后的两个月里，他狂热地四处呼吁，向各个部门写报告提建议，终于，北京市科协认可了他的这个想法，同意借给他200元钱，并开证明准许他在银行开一个账户。12月23日，在美国硅谷传奇的鼓舞下，陈春先在中关村一个仓库的一角办起了国内第一个民营科技实体：“北京等离子体学会先进技术发展服务部”。跟陈春先一起跳进商海的还有中科院物理所、电子所、力学所的 14个科研人员。日后，中关村成为中国最重要的科研产品集散地，陈春先无疑是第一个先驱。1980年的北京之冬十分寒冷，整个12月共下了六场鹅毛大雪，有报道说，这年冬天的下雪量是近二十年来最大的一次。陈春先骑着自行车日日踏雪跑业务，他的服务部在开业两个月后终于接到了第一单生意，海淀区一个街道小厂的厂长问上门兜售业务的核聚变科学家陈春先：“你能帮我们解决一下电源上的问题吗？”陈春先愣了一下，然后说，“当然能，你可以给多少钱？”<br /><br />    中关村要真正热闹起来，还要等三到四年。在陈春先办服务部的当时，却引起中科院内外很大的震动，几乎所有的人都认为他不务正业。这时，出身巴蜀的陈春先表现出川人特有的倔犟，他像疯了一样地四处去跑业务，这位研究艰深的核聚变技术的科学家不得不为15个人的生存做“稻粱谋”。在创业的第一年，他的服务部有了两万多元的收入，这在当时不算是一个小数目，陈春先因而给大家每人每月发了15元的津贴，这件事在清贫的中科院里顿时溅起轩然大波，告状的人忿忿地说，陈春先搞歪门邪道，居然自己给自己长了两级工资。到1983年，陈春先签订了27个合同，与海淀区的4个集体所有制的小工厂建立了技术协作关系，还帮助海淀区创建了海淀新技术实验厂和3个技术服务机构。陈春先为服务部所设定的经营原则后来成为中国民营高科技公司创办的共同规律，那就是：科技人员走出研究院所，遵循科技转化规律，市场经济规律，不要国家拨款，不占国家编制，自筹资金、自负盈亏、自主经营、依法自主决策。在他被怀疑、辱骂和嘲笑的身后，渐渐地，在中关村一带出现了零星的技术小公司。在媒体的报道下，陈春先的实践引起了上层的关注，当时主管经济工作的胡启立、方毅都做了批示，对他大为褒扬。<br /><br />    在这些举措的触动下，海淀区放宽了中关村办公司的政策。1984年，四通、信通、科海、京海及后来非常著名的联想公司相继诞生，“中关村电子一条街”初具规模，到1992年，这里的民营科技公司已达到5180家。<br /><br />    陈春先的研究方向是高深的核聚变，他参与创建了中国第一个核聚变基地，在中科院物理所建立了国内第一个托卡马克装置。而在中关村，他的这些专业几乎都派不上用场。从1980年以后，陈春先基本上放弃了学术研究。他把服务部改组成华夏硅谷公司，只要有生意上门他都乐此不疲地去谈判，他的公司做过的最大一笔业务是帮助一家美国公司做数据录入，他为此聘用了100多个大学生，1000个字符挣0.4元，如果顺利，一年可以得到30万美元的收入，但是这个业务后来也半途流产了。<br /><br />    陈春先显然不是一个优秀的经营者，在他的首倡下，中关村日渐规模膨胀，而他的公司却始终委靡不大，与联想、方正、同方等后起之秀不可同日而语。十多年来，他多次卷入经济纠纷，甚至还先后两次遭人绑架。他对人感慨说：“思想活跃也好，能悟出潜在的增值地方也罢，都不等于能够办好公司。相反，办好公司的企业家大都是搞营销、搞金融，有很强管理能力的人，而不是真正的科学家。我不是一个成功的企业家，这一点没有什么好回避的。”<br /><br />    陈春先晚年成为一个“历史人物”，平日无人记挂，到了某些纪念日则有媒体上门采访一二。很多人以为，他当年若一直在实验室工作，将成一个伟大的科学家。而他自己则说了这样的一段话：“我觉得每一代人只能做他当时认为最重要的事。人活着总要做点事，做了这件，也许就要放弃那一件。我做事从不后悔，即使做了较为愚蠢的事，也不后悔，因为时间总是在往前走的。”<br /><br />    陈春先是一个倔犟的四川成都人。他很应该被人长久的纪念。互联网上有一个专门的陈春先纪念网站（<a href="http://www.chenchunxian.com" target="_blank">http://www.chenchunxian.com</a>）。除了几个知情人，那是一个几乎被彻底遗忘的网站。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/184612#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 20 Apr 2008 17:42:06 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/184612</link>
        <guid>http://iunknown.javaeye.com/blog/184612</guid>
      </item>
      <item>
        <title>[zz]GB2312/GBK/GB18030/BIG5 的历史</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/170080" style="color:red;">http://iunknown.javaeye.com/blog/170080</a>&nbsp;
          发表时间: 2008年03月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://iask.sina.com.cn/b/7837434.html?from=related" target="_blank">http://iask.sina.com.cn/b/7837434.html?from=related</a><br /><br />GBK中的“K”是扩展的意思，而GB2312中的“2312”以及GB18030中的“18030”是国家标准的代号，BIG5是港澳台地区的编码。<br />下面详细介绍一下字库情况，你就可看出其区别：<br />（一）GB2312-80字库<br />从1975年开始，我国为了研究汉字的使用频度，进行了大规模的字频统计工作，内容包括工业、农业、军事、科技、政治、经济、文学、艺术、教育、体育、医药卫生、天文地理、自然、化学、文字改革、考古等多方面的出版物，在数以亿计的浩翰文献资料中，统计出实际使用的不同的汉字数为6335个，而其中有 3000多个汉字的累计使用频度达到了99.9%，而另外的3000多个累计频度不到0.1%，说明了常用汉字与次常用汉字的数量不足7000个，这就为国家制定汉字库标准提供了依据。1980年颁布了《信息交换用汉字编码字符集--基本集》的国标交换码，国家标准号为：GB2312-80，选入了 6763个汉字，分为两级，一级字库中有3755个，是常用汉字，二级字库中有3008个，是次常用汉字；还选入了682个字符，包含有数字、一般符号、拉丁字母、日本假名、希腊字母、俄文字母、拼音符号、注音字母等。<br />（二）大字符集字库（又叫GBK字库）<br />国际标准化组织为了将世界各民族的文字进行统一编码，制定了UCS标准。根据这一标准，中、日、韩三国共同制定了《CJK统一汉字编码字符集》，其国际标准号为：ISO/IEC10646，国家标准号为：GB13000-90，该汉字编码字符集就是通常人们所说的大字符集，它编入了20902个汉字，收集了大陆一二级字库中的简体字，台湾《通用汉字标准交换码》中的繁体字，58个香港特别用字和92个延边地区朝鲜族“吏读”字，甚至涵盖了日文与韩文中的通用汉字，满足了方方面面的需要。Windows95/98/NT/2000中都装入了大字符集汉字库，人们一般称它为GBK字库。有了GBK字库，还要有对应的汉字输入法，才能输入其中的全部汉字，如果某种汉字输入法仅编入了一二级字库，仍然只能输入6763个汉字。<br />（三）台湾 BIG5 字库<br />港澳台地区普遍使用台湾的《通用汉字标准交换码》，地区标准号为：CNS11643，选入了13 000多个繁体汉字，这就是人们讲的BIG5码，或叫大五码。 钱码的“海外繁体版”编入了BIG5字库，能输入13 000多个繁体汉字。<br />四）新标准汉字库 （GB18030-2000）<br />2000年3月，国家信息产业部和质量技术监督局在北京联合发布了两项新标准，一项叫做《信息技术和信息交换用汉字编码字符集、基本集的扩充》，国家标准号为：GB18030-2000，收录了27533个汉字，还收录了藏、蒙、维等主要少数民族的文字，以期一举解决邮政、户政、金融、地理信息系统等生僻汉字与主要少数民族语言的输入，该标准于2000年12月31日强制执行；另一项是《信息技术和数字键盘汉字输入通用要求》，国家标准号是： GB／T18031-2000，为数字键盘输入提供了统一的标准。 新标准汉字库已经公布，迫切需要与之相应的输入方法。<br />（五）方正超大字符集<br />方正超大字符集字体包括了上面提到的全部汉字以及在第二平面中(42,711)选出的36,862个在中国大陆，香港特别行政区(以及部分台湾地区)使用的汉字。因此包括西文等常用字符在内，宋体-方正超大字符集共包括65,531个字符。这是目前包含字数最全的字库。要安装该字库需在安装WinXP时采用自定义安装，选择安装宋体-方正超大字符集，但是一般的输入法是无法打出这么多的字的，但可以用“插入”—“符号”的方法选择插入。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/170080#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 11 Mar 2008 10:51:03 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/170080</link>
        <guid>http://iunknown.javaeye.com/blog/170080</guid>
      </item>
      <item>
        <title>基于 pull 的 mime 解释器的资料</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/169970" style="color:red;">http://iunknown.javaeye.com/blog/169970</a>&nbsp;
          发表时间: 2008年03月10日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://weblogs.java.net/blog/jitu/archive/2007/10/index.html" target="_blank">http://weblogs.java.net/blog/jitu/archive/2007/10/index.html</a><br /><br />New project mimepull allows applications to access MIME attachments in a streaming fashion.  Often times,  larger MIME messages cannot be loaded into memory. Hence the whole message or attachment parts are written to a file system and access to the attachment parts is provided using those files.<br /><br />But in some cases, the MIME attachment parts can be accessed by applications in a streaming fashion, provided:<br /><br />    * The parts are accessed orderly(as they appear in the stream)<br />    * The parts are accessed only once.<br /><br /><br />http://www.mail-archive.com/server-dev@james.apache.org/msg02000.html<br /><br />http://www.interactivecode.com/perl-18/raw-body-parts-mime-parser-41309/
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/169970#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 10 Mar 2008 20:55:18 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/169970</link>
        <guid>http://iunknown.javaeye.com/blog/169970</guid>
      </item>
      <item>
        <title>大航海时代4加强版</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/169417" style="color:red;">http://iunknown.javaeye.com/blog/169417</a>&nbsp;
          发表时间: 2008年03月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          上周日开始玩，选李华梅，用来半天时间度过了没有地方舰队的艰难时刻。<br />今天接着玩，凭借地方舰队带来的金钱，组织了 3 支铁甲船舰队，一路为主帅护航。<br />基本上都是以 迅雷不及掩耳盗铃之势 灭掉了对手，在各个海域做到了势力第一。<br /><br />印度洋，地中海，北海，非洲，东亚，新大陆，东南亚 逐个找到了证。<br />其中印度洋，地中海，北海都很简单。后面的四个就比较麻烦了。<br />关键是很多同业公会交代的任务都忘记了。<br />在新大陆转了很多圈都没见到 幽灵船 ，在快失去耐心的时候，终于出现了。<br />在东南亚，鲨鱼的幼子原来在 伊斯坦堡 的时候已经用了，当时也没留意。<br />结果在东南亚不断转圈，也打了几次鲨鱼，但就是拿不到鲨鱼幼子。<br />后来 baidu 了一下，才知道可以用 鱼子酱 替代 鱼翅。<br /><br /><img src="http://lh5.google.com/stephen.nil/R9KrbYix5vI/AAAAAAAAAF8/D4gnpATU04w/lhm4.bmp?imgmax=512" /><br /><img src="http://lh6.google.com/stephen.nil/R9Kraoix5uI/AAAAAAAAAF0/jn-3EEPB8pM/lhm3.bmp?imgmax=512" /><br /><img src="http://lh5.google.com/stephen.nil/R9KraYix5tI/AAAAAAAAAFs/auRE1cHuQRY/lhm2.bmp?imgmax=512" /><br /><img src="http://lh5.google.com/stephen.nil/R9KraYix5sI/AAAAAAAAAFk/NjeMCZh1_KI/lhm.bmp?imgmax=512" />
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/169417#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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, 08 Mar 2008 23:15:48 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/169417</link>
        <guid>http://iunknown.javaeye.com/blog/169417</guid>
      </item>
      <item>
        <title>[zz]Distributing Lucene Indexing and Searchin</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/160066" style="color:red;">http://iunknown.javaeye.com/blog/160066</a>&nbsp;
          发表时间: 2008年01月29日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://www.mail-archive.com/lucene-user@jakarta.apache.org/msg12709.html" target="_blank">http://www.mail-archive.com/lucene-user@jakarta.apache.org/msg12709.html</a><br /><br />A clever way to do this is to take advantage of Lucene's index file structure. Indexes are directories of files. As the index changes through additions and deletions most files in the index stay the same. So you can efficiently synchronize multiple copies of an index by only copying the files that change.<br /><br />The way I did this for Technorati was to:<br /><br /><br />1. On the index master, periodically checkpoint the index. Every minute or so the IndexWriter is closed and a 'cp -lr index index.DATE' command is executed from Java, where DATE is the current date and time. This efficiently makes a copy of the index when its in a consistent state by constructing a tree of hard links. If Lucene re-writes any files (e.g., the segments file) a new inode is created and the copy is unchanged.<br /><br />2. From a crontab on each search slave, periodically poll for new checkpoints. When a new index.DATE is found, use 'cp -lr index index.DATE' to prepare a copy, then use 'rsync -W --delete master:index.DATE index.DATE' to get the incremental index changes. Then atomically install the updated index with a symbolic link (ln -fsn index.DATE index).<br /><br />3. In Java on the slave, re-open 'index' it when its version changes. This is best done in a separate thread that periodically checks the index version. When it changes, the new version is opened, a few typical queries are performed on it to pre-load Lucene's caches. Then, in a synchronized block, the Searcher variable used in production is updated.<br /><br />4. In a crontab on the master, periodically remove the oldest checkpoint indexes.<br /><br />Technorati's Lucene index is updated this way every minute. A mergeFactor of 2 is used on the master in order to minimize the number of segments in production. The master has a hot spare.
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/160066#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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>Tue, 29 Jan 2008 10:56:05 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/160066</link>
        <guid>http://iunknown.javaeye.com/blog/160066</guid>
      </item>
      <item>
        <title>一些关于 consistent hashing 的资料</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/156759" style="color:red;">http://iunknown.javaeye.com/blog/156759</a>&nbsp;
          发表时间: 2008年01月16日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://cn.last.fm/user/RJ/journal/2007/04/10/392555/" target="_blank">http://cn.last.fm/user/RJ/journal/2007/04/10/392555/</a><br /><br />libketama - a consistent hashing algo for memcache clients<br /><br />http://www.isthe.com/chongo/tech/comp/fnv/<br /><br />Fowler / Noll / Vo (FNV) Hash<br /><br />http://lists.danga.com/pipermail/memcached/2007-April/003834.html
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/156759#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 16 Jan 2008 22:42:47 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/156759</link>
        <guid>http://iunknown.javaeye.com/blog/156759</guid>
      </item>
      <item>
        <title>SPNetKit：http/smtp/pop3/memcached 的客户端库</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/155420" style="color:red;">http://iunknown.javaeye.com/blog/155420</a>&nbsp;
          发表时间: 2008年01月13日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          SPNetKit 主要是一个常见应用层协议的客户端库，使用 C++ 实现，目前实现了 http，smtp，pop3，memcached 。<br />对于每个客户端都带有一个命令行的示范例子。<br /><br />http/smtp/pop3 除了 TCP 实现之外，也能支持 SSL (基于 openssl)。<br />memcached client 支持了最新的 memcached 1.2.4 中新增加的 'append', 'prepend', 'gets', and 'cas' 命令。<br /><br />除了这些客户端实现之外，还包括一个读取 ini 配置文件的类，base64 编码和解码类。<br /><br />主页：<a href="http://code.google.com/p/spnetkit/" target="_blank">http://code.google.com/p/spnetkit/</a><br />下载：<a href="http://spnetkit.googlecode.com/files/spnetkit-0.1.1.src.tar.gz" target="_blank">http://spnetkit.googlecode.com/files/spnetkit-0.1.1.src.tar.gz</a>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/155420#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 13 Jan 2008 17:41:52 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/155420</link>
        <guid>http://iunknown.javaeye.com/blog/155420</guid>
      </item>
      <item>
        <title>svn 操作摘要</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/155317" style="color:red;">http://iunknown.javaeye.com/blog/155317</a>&nbsp;
          发表时间: 2008年01月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          tags<br /><pre name="code" class="java">
svn copy https://xxxx.googlecode.com/svn/trunk/ https://xxxx.googlecode.com/svn/tags/0.1 -m "0.1 release" --username xxxx
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/155317#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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, 12 Jan 2008 21:45:28 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/155317</link>
        <guid>http://iunknown.javaeye.com/blog/155317</guid>
      </item>
      <item>
        <title>Leader/Follower 进程池设计思路</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/153240" style="color:red;">http://iunknown.javaeye.com/blog/153240</a>&nbsp;
          发表时间: 2008年01月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          看了 <a href="http://www.fmc-modeling.org/category/projects/apache/amp/4_3Multitasking_server.html" target="_blank">apache 的分析文章</a>之后，觉得里面的图非常好地描述了 apache 的结构。也尝试用 visio 画一下 <a href="http://iunknown.javaeye.com/blog/147010" target="_blank">spprocpool</a> 的结构。<br /><br />对图中各个部分的说明：<br />1. MasterServer 通过 Fork 创建 ProcessManager ，ProcessPool 作为 ProcessManager 在 MasterServer 中的存根<br />2. 在 ProcessPool 和 ProcessManager 存在一个 ManagerPipe 管道<br />3. 当 MasterServer 需要更多的子进程的时候，MasterServer 通过 ProcessPool 对象向 ProcessManager 发起创建 ChildServer 的请求4. ProcessManager 是创建 ChildServer 的唯一一个地方<br />5. 在 MasterServer 和 ChildServer 之间存在一个 ChildPipe 管道<br />6. MasterServer 只负责监控子进程的状态（包括：忙、闲、异常退出），监控子进程的状态完全是通过 ChildPipe 来进行的；MasterServer 使用 select 可以同时监控所有的 ChildPipe 的可读状态；当一个 ChildPipe 可读的时候，MasterServer 读入内容，如果读入的最后一个字节为 BusyChar，设置 Child 的状态为 Busy；如果为 IdleChar ，设置 Child 的状态为 Idle；如果读入 0 字节，那么表示 Child 已经关闭 ChildPipe ，也就表明 Child 已经异常退出了。<br />7. ChildServer 被创建出来之后，就在 ListenFd 上 accept ，如果 accept 成功就通过 ChildPipe 发送一个 BusyChar，然后开始处理；处理结束之后，再通过 ChildPipe 发送一个 IdleChar；接着检查 PipeOfDeath 是否有内容，如果读到有内容，那么子进程自行退出；<br /><br />关于几个主要文件句柄的传递说明：<br />1. ManagerPipe ：MasterServer 创建，传递给 ProcessManager（通过 Fork）<br />2. ListenFd ：MasterServer 创建，传递给 ProcessManager（通过 Fork），由 ProcessManager 传递给 ChildServer（通过Fork）<br />3. PipeOfDeath ：MasterServer 创建，传递给 ProcessManager（通过 Fork），由 ProcessManager 传递给 ChildServer（通过 Fork）,MasterServer 持可写的一端，各个 ChildServer 持可读的一端；PipeOfDeath 在 MasterServer 只有一个句柄；<br />4. ChildPipe ：MasterServer 创建，传递给 ProcessManager（通过 Send_Fd），由 ProcessManager 传递给 ChildServer（通过 Fork）,ChildPipe 在 MasterServer 有多个，每个 ChildServer 有一个 ChildPipe；<br /><br /><br /><img src="http://lh3.google.com/stephen.nil/R387OKgDxqI/AAAAAAAAAEE/qwdpTrNkYQo/%E7%BB%98%E5%9B%BE3.jpg?imgmax=512" />
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/153240#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 04 Jan 2008 23:47:51 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/153240</link>
        <guid>http://iunknown.javaeye.com/blog/153240</guid>
      </item>
      <item>
        <title>machine `x86_64-unknown' not recognized</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/149481" style="color:red;">http://iunknown.javaeye.com/blog/149481</a>&nbsp;
          发表时间: 2007年12月19日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          checking host system type... Invalid configuration `x86_64-unknown-linux-gnu': machine `x86_64-unknown' not recognized<br /><br />在做 configure 的时候，报上述的错误。<br />解决方案：<br />把 /usr/share/libtool/config.guess 覆盖到相关软件自带的config.guess<br />把 /usr/share/libtool/config.sub 覆盖到相关软件自带的config.sub<br />./configure --enable-shared --enable-static<br /><br />这样就可以通过了。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/149481#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 19 Dec 2007 16:57:12 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/149481</link>
        <guid>http://iunknown.javaeye.com/blog/149481</guid>
      </item>
      <item>
        <title>SPProcPool: Unix/Linux 上的进程池服务器框架</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/147010" style="color:red;">http://iunknown.javaeye.com/blog/147010</a>&nbsp;
          发表时间: 2007年12月09日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          SPProcPool 是一个 linux/unix 平台上的进程池服务器框架，使用 c++ 实现。主要包含了几种不同类型的进程池的实现：<br />一个基于 Leader/Follower 模式的服务器端进程池（类似 apache 的 prefork 模型）；<br />一个组合了 Prefork 和线程池的服务器端框架（类似 apache 的 worker 模型）；<br />一个基于文件句柄传递的服务器端进程池；<br />一个用于非服务器端的，能够在多线程或事件驱动环境下使用的进程池。<br /><br />主页：<a href="http://code.google.com/p/spprocpool/" target="_blank">http://code.google.com/p/spprocpool/</a><br />下载：<a href="http://freshmeat.net/redir/spprocpool/72480/url_tgz/spprocpool-0.1.src.tar.gz" target="_blank">spprocpool</a><br /><br />关于进程池服务器框架，在《unix网络编程（第二版）》的第 27 章，详细地描述了多种不同的实现方式。<br />基于 Leader/Follower 模式的实现：27.6 TCP 预先派生子进程服务器程序，accept 无上锁保护<br />基于文件句柄传递：27.9 TCP 预先派生子进程服务器程序，传递描述字<br /><br />关于非服务器端的，能够在多线程或事件驱动环境下使用的进程池，这里做一个比较详细的说明。<br /><br />多线程的好处是各个线程能够共享一个地址空间，因此对一些需要全局排序来调度的任务，使用多线程可以比较方便地实现。比如类似 postfix/qmgr 的模块，如果使用多线程的话，那么所有的邮件能够在一个优先队列中排队，按队列顺序进行投递；如果投递失败了，那么重新插入队列。<br />但另一方面，如果具体的任务处理部分已经有了实现，但不是线程安全的，这种问题要怎么来解决呢？<br /><br />一个最直观的解决方法是每个任务直接 fork 一次。但是这种做法有几个细节问题需要认真考虑：<br />1.在子进程中如何把结果返回给调度进程？常见的方法是使用 pipe <br />2.每个任务 fork 一次，估计很多人的第一反应就是性能会怎么样？<br />3.如果调度进程中，除了负责 fork 的线程，还有其他的线程存在，那么就存在 fork-with-thread 的问题。<br />>>具体的内容可以参考：<a href="http://www.opengroup.org/onlinepubs/000095399/functions/fork.html" target="_blank">http://www.opengroup.org/onlinepubs/000095399/functions/fork.html</a><br /><br />针对上面存在的问题，在每个任务直接 fork 一次的基础上，做了一些改进，就形成了这样的一个进程池实现：<br />1.在前面的方案中，存在调度进程（Sched）和工作进程（Worker）这两类进程。<br />>>为了避免 fork-with-thread 的问题，再增加一类管理进程（Manager）。管理进程的主要职责就是负责 fork 工作进程。<br />2.通常 Manager 是由 Sched fork 出来的，它们之间存在一条通信的 pipe （MgrPipe） 。<br />>>创建一个新的工作进程的流程如下：Sched 创建一个 pipe （WorkerPipe），把其中的一端用 send_fd 的方法发送给 Manager，<br />>>然后 Manager fork 一个 Worker 出来，并且把 WorkerPipe 传递给 Worker 。这样就在 Sched 和 Worker 之间建立了一个 Pipe 。<br />3.Worker 在被 fork 出来之后，通常就阻塞在读 WorkerPipe 上面。Sched 通过 WorkerPipe 发送任务给 Worker 。<br />>>Worker 完成任务之后，通过 WorkerPipe 发送结果给 Sched 。Worker 可以不断地重复这个过程，这样就达到了一个池的效果。<br />4.对于使用 libevent 这类事件驱动类型的程序，这个进程池也能方便地被调用。<br />>>因为 Worker 曝露出来的是一个 PipeFd，能够方便地加入到 libevent 的事件循环中。这类事件驱动类的程序，<br />>>通常使用单线程实现，当具体的任务处理可能需要耗费比较长时间的时候，就需要使用多线程或者多进程来辅助了。<br /><br />SPProcPool 提供了 3 个服务器框架：<br />SP_ProcInetServer（传递文件句柄）<br />SP_ProcLFServer（Leader/Follower模型）<br />SP_ProcMTServer（Worker模型）<br /><br />它们的定义很类似： <br /><br /><pre name="code" class="java">
class SP_ProcInetServer {
public:
    SP_ProcInetServer( const char * bindIP, int port,
            SP_ProcInetServiceFactory * factory );
    virtual ~SP_ProcInetServer();

    virtual int start();
};

class SP_ProcLFServer {
public:
    SP_ProcLFServer( const char * bindIP, int port,
            SP_ProcInetServiceFactory * factory );
    virtual ~SP_ProcLFServer();

    virtual int start();
};

class SP_ProcMTServer {  
public:  
    SP_ProcMTServer( const char * bindIP, int port,  
            SP_ProcInetServiceFactory * factory );  
    virtual ~SP_ProcMTServer();  
  
    virtual int start();  
};
</pre><br /><br />从接口中可以看到，要使用这些框架，需要提供一个 SP_ProcInetServiceFactory 类的实例。这个类相关的定义如下： <br /><br /><pre name="code" class="java">
class SP_ProcInetService {
public:
    virtual ~SP_ProcInetService();

    virtual void handle( int socketFd ) = 0;
};

class SP_ProcInetServiceFactory {
public:
    virtual ~SP_ProcInetServiceFactory();

    virtual SP_ProcInetService * create() const = 0;

    virtual void workerInit( const SP_ProcInfo * procInfo );

    virtual void workerEnd( const SP_ProcInfo * procInfo );
};
</pre><br /><br />这里使用的是典型的抽象工厂方法。在工厂类中，除了 create 方法之外，还有两个特别的方法：workerInit 和 workerEnd 。workerInit 在子进程开始运行的时候被调用，workerEnd 在子进程退出的时候被调用。在 Service 类中，只有一个 handle 方法，它的参数就是已经 accept 到 socket 。<br /><br />下面以一个简单的服务器为例进行说明。这个服务器是模仿《unix网络编程（第二版）》（中文版）第27章的服务器。服务器从 socket 读入包含一个数字的一行，然后根据这个数字返回相应的内容。<br /><br />要实现这个简单的服务器例子，代码如下： <br /><br /><pre name="code" class="java">
class SP_ProcUnpService : public SP_ProcInetService {
public:
    SP_ProcUnpService() {}
    virtual ~SP_ProcUnpService() {}

    virtual void handle( int sockfd ) {
        int ntowrite;
        ssize_t nread;
        char line[MAXLINE], result[MAXN];
    
        for ( ; ; ) {
            if ( (nread = read(sockfd, line, MAXLINE)) == 0) {
                return;     /* connection closed by other end */
            }
    
            /* line from client specifies #bytes to write back */
            ntowrite = atol(line);
            if ((ntowrite &lt;= 0) || (ntowrite > MAXN)) {
                syslog( LOG_WARNING, "WARN: client request for %d bytes", ntowrite);
                exit( -1 );
            }
        
            SP_ProcPduUtils::writen(sockfd, result, ntowrite);
        }       
    }           
};   

class SP_ProcUnpServiceFactory : public SP_ProcInetServiceFactory {
public:     
    SP_ProcUnpServiceFactory() {}
    virtual ~SP_ProcUnpServiceFactory() {}
            
    virtual SP_ProcInetService * create() const {
        return new SP_ProcUnpService();
    }           

    virtual void workerInit( const SP_ProcInfo * procInfo ) {
        signal( SIGINT, SIG_DFL );
        printf( "pid %d start\n", (int)procInfo->getPid() );
    }

    virtual void workerEnd( const SP_ProcInfo * procInfo ) {
        printf( "pid %d exit, pipeFd %d, requests %d, lastActiveTime %ld\n",
                (int)procInfo->getPid(), procInfo->getPipeFd(),
                procInfo->getRequests(), procInfo->getLastActiveTime() );
    }
};

int main( int argc, char * argv[] )
{
    SP_ProcMTServer server( "", 1770, new SP_ProcUnpServiceFactory() );

    server.start();

    return 0;
}
</pre>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/147010#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 09 Dec 2007 11:30:45 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/147010</link>
        <guid>http://iunknown.javaeye.com/blog/147010</guid>
      </item>
      <item>
        <title>Thrift：Facebook.com 的核心框架</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/146800" style="color:red;">http://iunknown.javaeye.com/blog/146800</a>&nbsp;
          发表时间: 2007年12月07日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <a href="http://developers.facebook.com/thrift/" target="_blank">http://developers.facebook.com/thrift/</a><br /><br />Thrift is a software framework for scalable cross-language services development. It combines a powerful software stack with a code generation engine to build services that work efficiently and seamlessly between C++, Java, Python, PHP, and Ruby. Thrift was developed at Facebook, and we are now releasing it as open source.<br /><br />在它的文档中，自比为 SOAP，CORBA，COM 一类的框架。看了一下它的功能，在 cross-language 方面，的确很酷，提供了很多语言的代码生成器，比如 cpp，java，python，php，ruby，perl 这些大家比较熟悉的，还包括一些看起来很酷的语言，比如 erlang，ocaml。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/146800#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Fri, 07 Dec 2007 21:42:58 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/146800</link>
        <guid>http://iunknown.javaeye.com/blog/146800</guid>
      </item>
      <item>
        <title>lkcd 的配置</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/127746" style="color:red;">http://iunknown.javaeye.com/blog/127746</a>&nbsp;
          发表时间: 2007年09月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          suse linux 自带了 lkcd 安装包，安装之后，还有些配置项需要修改一下。<br />默认是使用 网络 方式，改成使用本地文件方式，记录一下<br /><br /><pre name="code" class="java">
/etc/sysconfig/dump
DUMP_ACTIVE="1"
DUMPDEV="/dev/vmdump"
DUMPDIR="/var/log/dump"
DUMP_LEVEL="2"
DUMP_COMPRESS="2"
DUMP_FLAGS="0x80000000"
DUMP_SAVE="1"
PANIC_TIMEOUT="5"
BOUNDS_LIMIT=10
KEXEC_IMAGE=/boot/vmlinuz
KEXEC_CMDLINE="root console=tty0"
TARGET_HOST="localhost"
TARGET_PORT=6688
SOURCE_PORT=6688
</pre><br /><br />测试 lkcd <br />1.lkcd config<br />2.lkcd dump  这时候 linux 会被重启<br />3.linux 重启之后，login 进去之后， lkcd save<br />4.lcrash -d dump.0 -t kerntypes.0 -m /boot/System.map-xxx
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/127746#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 27 Sep 2007 23:22:04 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/127746</link>
        <guid>http://iunknown.javaeye.com/blog/127746</guid>
      </item>
      <item>
        <title>分析模式之概念模型</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/112009" style="color:red;">http://iunknown.javaeye.com/blog/112009</a>&nbsp;
          发表时间: 2007年08月14日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          分析还包括透过表面需求进行深入分析，以便获得一个有关该问题<strong>本质</strong>内容的智力模型。<br />但在很多企业里，相关的规律并不易于让人了解，我们必须努力去揭示它们。为此我们创建了概念模型--一种允许我们了解并<strong>简化</strong>问题的智力模型。<br />需要特别提醒的是，概念模型是一种人工制品。开发人员用来创建类似于斯诺克台球模拟程序这类事物的运动规律在现实世界中并不存在；它们是有人类创造的，表征了现实世界的某种模型。从工程角度来讲，这些模型非常有效，因为它们是我们能够<strong>更深刻</strong>地理解现实世界所发生的事情。<br /><br />不存在正确或者错误的模型，只存在对手头的工作更适用的模型。
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/112009#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></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 14 Aug 2007 06:54:43 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/112009</link>
        <guid>http://iunknown.javaeye.com/blog/112009</guid>
      </item>
      <item>
        <title>手工测试 ssl 服务器的工具</title>
        <author>iunknown</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://iunknown.javaeye.com">iunknown</a>&nbsp;
          链接：<a href="http://iunknown.javaeye.com/blog/111259" style="color:red;">http://iunknown.javaeye.com/blog/111259</a>&nbsp;
          发表时间: 2007年08月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          在为基于文本命令行协议的服务器（echo，smtp，pop，http一类的）增加 ssl 支持的时候，通常期望能够有一个 stelnet 工具，类似于平时用来测试文本命令行服务器的 telnet 工具，不过就要求 stelnet 能够支持 ssl 协议。一般来说，开发这类服务器，telnet 都是最基本的调试工具。有了这个 stelnet 工具之后，对于开发 ssl 的服务器有很大的帮助。<br /><br />用 google search 了一下，发现有人准备做这个东西，但在 sf 上只有项目说明，还没有任何代码下载。接着就发现了下面这个链接<br /><a href="http://russell.rucus.net/blog/Geek/stelnet" target="_blank">http://russell.rucus.net/blog/Geek/stelnet</a><br /><br />原来 openssl 库中早就有这样的工具了。<br /><br /><div class="quote_title">引用</div><div class="quote_div">bash-2.05a$ cat stelnet <br />#!/bin/sh<br /><br />exec openssl s_client -connect $1:$2 -crlf -CApath $HOME/spserver/democa.crt<br /></div><br /><br />用法和普通的 telnet 一样，下面是用来测试的 <a href="http://iunknown.javaeye.com/blog/59804" target="_blank">spserver</a> 中自带的 testhttps 的例子<br /><pre name="code" class="java">
./stelnet 127.0.0.1 8080
......
......
GET / HTTP/1.1
Host: 127.0.0.1

HTTP/1.1 200 OK
Content-Length: 171
Date: Sat, 11 Aug 2007 16:12:11 HKT
Content-Type: text/html; charset=ISO-8859-1
Server: sphttp/spserver

&lt;html>&lt;head>&lt;title>Welcome to simple http&lt;/title>&lt;/head>&lt;body>&lt;p>The requested URI is : /.&lt;/p>&lt;p>Client IP is : 127.0.0.1.&lt;/p>&lt;p>Header - Host: 127.0.0.1&lt;p>&lt;/body>&lt;/html>

</pre>
          <br/>
          <span style="color:red;">
            <a href="http://iunknown.javaeye.com/blog/111259#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</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, 11 Aug 2007 16:13:43 +0800</pubDate>
        <link>http://iunknown.javaeye.com/blog/111259</link>
        <guid>http://iunknown.javaeye.com/blog/111259</guid>
      </item>
  </channel>
</rss>