﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-紫月城游戏软件-随笔分类-设计模式</title><link>http://www.cppblog.com/kevinlynx/category/7299.html</link><description>低调做技术</description><language>zh-cn</language><lastBuildDate>Fri, 06 Jun 2008 16:20:42 GMT</lastBuildDate><pubDate>Fri, 06 Jun 2008 16:20:42 GMT</pubDate><ttl>60</ttl><item><title>Proactor和Reactor模式_继续并发系统设计的扫盲</title><link>http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html</link><dc:creator>Kevin Lynx</dc:creator><author>Kevin Lynx</author><pubDate>Fri, 06 Jun 2008 05:25:00 GMT</pubDate><guid>http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html</guid><wfw:comment>http://www.cppblog.com/kevinlynx/comments/52356.html</wfw:comment><comments>http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/kevinlynx/comments/commentRss/52356.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kevinlynx/services/trackbacks/52356.html</trackback:ping><description><![CDATA[<p><font size=2>6.6.2008 </font>
<p><font size=2>Kevin Lynx </font>
<p><font size=2>Proactor和<a href="http://en.wikipedia.org/wiki/Reactor_pattern" target=_blank>Reactor</a>都是并发编程中的设计模式。在我看来，他们都是用于派发/分离IO操作事件的。这里所谓的<br>IO事件也就是诸如read/write的IO操作。"派发/分离"就是将单独的IO事件通知到上层模块。两个模式不同的地方<br>在于，Proactor用于异步IO，而Reactor用于同步IO。 </font>
<p><font size=2>摘抄一些关键的东西： </font>
<p><font size=2>"<br>Two patterns that involve event demultiplexors are called Reactor and Proactor [1]. The Reactor patterns <br>involve synchronous I/O, whereas the Proactor pattern involves asynchronous I/O.<br>" </font>
<p><font size=2>关于两个模式的大致模型，从以下文字基本可以明白： </font>
<p><font size=2>"<br>An example will help you understand the difference between Reactor and Proactor. We will focus on the read <br>operation here, as the write implementation is similar. Here's a read in Reactor: </font>
<p><font size=2>* An event handler declares interest in I/O events that indicate readiness for read on a particular socket ;<br>* The event demultiplexor waits for events ;<br>* An event comes in and wakes-up the demultiplexor, and the demultiplexor calls the appropriate handler; <br>* The event handler performs the actual read operation, handles the data read, declares renewed interest in <br>&nbsp; I/O events, and returns control to the dispatcher . </font>
<p><font size=2>By comparison, here is a read operation in Proactor (true async): </font>
<p><font size=2>* A handler initiates an asynchronous read operation (note: the OS must support asynchronous I/O). In this <br>&nbsp; case, the handler does not care about I/O readiness events, but is instead registers interest in receiving <br>&nbsp; completion events;<br>* The event demultiplexor waits until the operation is completed ;<br>* While the event demultiplexor waits, the OS executes the read operation in a parallel kernel thread, puts <br>&nbsp; data into a user-defined buffer, and notifies the event demultiplexor that the read is complete ;<br>* The event demultiplexor calls the appropriate handler; <br>* The event handler handles the data from user defined buffer, starts a new asynchronous operation, and returns<br>&nbsp; control to the event demultiplexor. </font>
<p><font size=2>" </font>
<p><font size=2>可以看出，两个模式的相同点，都是对某个IO事件的事件通知(即告诉某个模块，这个IO操作可以进行或已经完成)。在结构<br>上，两者也有相同点：demultiplexor负责提交IO操作(异步)、查询设备是否可操作(同步)，然后当条件满足时，就回调handler。<br>不同点在于，异步情况下(Proactor)，当回调handler时，表示IO操作已经完成；同步情况下(Reactor)，回调handler时，表示<br>IO设备可以进行某个操作(can read or can write)，handler这个时候开始提交操作。 </font>
<p><font size=2>用select模型写个简单的reactor，大致为： </font>
<p><font size=2></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_0_3_Open_Image onclick="this.style.display='none'; Codehighlighter1_0_3_Open_Text.style.display='none'; Codehighlighter1_0_3_Closed_Image.style.display='inline'; Codehighlighter1_0_3_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_0_3_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_3_Closed_Text.style.display='none'; Codehighlighter1_0_3_Open_Image.style.display='inline'; Codehighlighter1_0_3_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span id=Codehighlighter1_0_3_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_0_3_Open_Text><span style="COLOR: #808080">///</span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;handler<br><img id=Codehighlighter1_18_124_Open_Image onclick="this.style.display='none'; Codehighlighter1_18_124_Open_Text.style.display='none'; Codehighlighter1_18_124_Closed_Image.style.display='inline'; Codehighlighter1_18_124_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_18_124_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_18_124_Closed_Text.style.display='none'; Codehighlighter1_18_124_Open_Image.style.display='inline'; Codehighlighter1_18_124_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_18_124_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_18_124_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onRead()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onWrite()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onAccept()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;dispatch<br><img id=Codehighlighter1_144_804_Open_Image onclick="this.style.display='none'; Codehighlighter1_144_804_Open_Text.style.display='none'; Codehighlighter1_144_804_Closed_Image.style.display='inline'; Codehighlighter1_144_804_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_144_804_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_144_804_Closed_Text.style.display='none'; Codehighlighter1_144_804_Open_Image.style.display='inline'; Codehighlighter1_144_804_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_144_804_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_144_804_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;poll()<br><img id=Codehighlighter1_174_696_Open_Image onclick="this.style.display='none'; Codehighlighter1_174_696_Open_Text.style.display='none'; Codehighlighter1_174_696_Closed_Image.style.display='inline'; Codehighlighter1_174_696_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_174_696_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_174_696_Closed_Text.style.display='none'; Codehighlighter1_174_696_Open_Image.style.display='inline'; Codehighlighter1_174_696_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_174_696_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_174_696_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;add&nbsp;fd&nbsp;in&nbsp;the&nbsp;set.<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/dot.gif"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;poll&nbsp;every&nbsp;fd</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;c&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;select(&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">read_fd,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">write_fd,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;c&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;)<br><img id=Codehighlighter1_329_690_Open_Image onclick="this.style.display='none'; Codehighlighter1_329_690_Open_Text.style.display='none'; Codehighlighter1_329_690_Closed_Image.style.display='inline'; Codehighlighter1_329_690_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_329_690_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_329_690_Closed_Text.style.display='none'; Codehighlighter1_329_690_Open_Image.style.display='inline'; Codehighlighter1_329_690_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_329_690_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_329_690_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;each&nbsp;fd&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;read_fd_set<br><img id=Codehighlighter1_386_533_Open_Image onclick="this.style.display='none'; Codehighlighter1_386_533_Open_Text.style.display='none'; Codehighlighter1_386_533_Closed_Image.style.display='inline'; Codehighlighter1_386_533_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_386_533_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_386_533_Closed_Text.style.display='none'; Codehighlighter1_386_533_Open_Image.style.display='inline'; Codehighlighter1_386_533_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_386_533_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_386_533_Open_Text><span style="COLOR: #000000">{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;fd&nbsp;can&nbsp;read<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_handler</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">onRead();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;fd&nbsp;can&nbsp;accept<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_handler</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">onAccept();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;each&nbsp;fd&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;the&nbsp;write_fd_set<br><img id=Codehighlighter1_593_680_Open_Image onclick="this.style.display='none'; Codehighlighter1_593_680_Open_Text.style.display='none'; Codehighlighter1_593_680_Closed_Image.style.display='inline'; Codehighlighter1_593_680_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_593_680_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_593_680_Closed_Text.style.display='none'; Codehighlighter1_593_680_Open_Image.style.display='inline'; Codehighlighter1_593_680_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_593_680_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_593_680_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;fd&nbsp;can&nbsp;write<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_handler</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">onWrite();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;setHandler(&nbsp;handler&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">_h&nbsp;)<br><img id=Codehighlighter1_739_768_Open_Image onclick="this.style.display='none'; Codehighlighter1_739_768_Open_Text.style.display='none'; Codehighlighter1_739_768_Closed_Image.style.display='inline'; Codehighlighter1_739_768_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_739_768_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_739_768_Closed_Text.style.display='none'; Codehighlighter1_739_768_Open_Image.style.display='inline'; Codehighlighter1_739_768_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_739_768_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_739_768_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_handler&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;_h;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;handler&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">_handler;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img id=Codehighlighter1_809_824_Open_Image onclick="this.style.display='none'; Codehighlighter1_809_824_Open_Text.style.display='none'; Codehighlighter1_809_824_Closed_Image.style.display='inline'; Codehighlighter1_809_824_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_809_824_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_809_824_Closed_Text.style.display='none'; Codehighlighter1_809_824_Open_Image.style.display='inline'; Codehighlighter1_809_824_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_809_824_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_809_824_Open_Text><span style="COLOR: #808080">///</span><span style="COLOR: #008000">&nbsp;application</span><span style="COLOR: #808080"></span></span><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyHandler&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;handler<br><img id=Codehighlighter1_858_965_Open_Image onclick="this.style.display='none'; Codehighlighter1_858_965_Open_Text.style.display='none'; Codehighlighter1_858_965_Closed_Image.style.display='inline'; Codehighlighter1_858_965_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_858_965_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_858_965_Closed_Text.style.display='none'; Codehighlighter1_858_965_Open_Image.style.display='inline'; Codehighlighter1_858_965_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_858_965_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_858_965_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onRead()<br><img id=Codehighlighter1_890_896_Open_Image onclick="this.style.display='none'; Codehighlighter1_890_896_Open_Text.style.display='none'; Codehighlighter1_890_896_Closed_Image.style.display='inline'; Codehighlighter1_890_896_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_890_896_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_890_896_Closed_Text.style.display='none'; Codehighlighter1_890_896_Open_Image.style.display='inline'; Codehighlighter1_890_896_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_890_896_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_890_896_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onWrite()<br><img id=Codehighlighter1_923_929_Open_Image onclick="this.style.display='none'; Codehighlighter1_923_929_Open_Text.style.display='none'; Codehighlighter1_923_929_Closed_Image.style.display='inline'; Codehighlighter1_923_929_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_923_929_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_923_929_Closed_Text.style.display='none'; Codehighlighter1_923_929_Open_Image.style.display='inline'; Codehighlighter1_923_929_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_923_929_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_923_929_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onAccept()<br><img id=Codehighlighter1_957_963_Open_Image onclick="this.style.display='none'; Codehighlighter1_957_963_Open_Text.style.display='none'; Codehighlighter1_957_963_Closed_Image.style.display='inline'; Codehighlighter1_957_963_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_957_963_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_957_963_Closed_Text.style.display='none'; Codehighlighter1_957_963_Open_Image.style.display='inline'; Codehighlighter1_957_963_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_957_963_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_957_963_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>在网上找了份Proactor模式比较正式的<a href="http://www.cppblog.com/Files/kevinlynx/proactor2.rar" target=_blank>文档</a>，其给出了一个总体的UML类图，比较全面： </font>
<p><a href="http://www.cppblog.com/images/cppblog_com/kevinlynx/WindowsLiveWriter/ProactorReactor__BCB1/proactor_uml.jpg"><img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=317 alt=proactor_uml src="http://www.cppblog.com/images/cppblog_com/kevinlynx/WindowsLiveWriter/ProactorReactor__BCB1/proactor_uml_thumb.jpg" width=692 border=0></a>
<p><font size=2>根据这份图我随便写了个例子代码： </font>
<p><font size=2></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;AsyIOProcessor<br><img id=Codehighlighter1_21_227_Open_Image onclick="this.style.display='none'; Codehighlighter1_21_227_Open_Text.style.display='none'; Codehighlighter1_21_227_Closed_Image.style.display='inline'; Codehighlighter1_21_227_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_21_227_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_21_227_Closed_Text.style.display='none'; Codehighlighter1_21_227_Open_Image.style.display='inline'; Codehighlighter1_21_227_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_21_227_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_21_227_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;do_read()<br><img id=Codehighlighter1_54_189_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_189_Open_Text.style.display='none'; Codehighlighter1_54_189_Closed_Image.style.display='inline'; Codehighlighter1_54_189_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_54_189_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_189_Closed_Text.style.display='none'; Codehighlighter1_54_189_Open_Image.style.display='inline'; Codehighlighter1_54_189_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_54_189_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_54_189_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000"><img src="http://www.cppblog.com/Images/dot.gif">send&nbsp;read&nbsp;operation&nbsp;to&nbsp;OS<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;read&nbsp;io&nbsp;finished.and&nbsp;dispatch&nbsp;notification</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_proactor</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">dispatch_read();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;Proactor&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">_proactor;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Proactor<br><img id=Codehighlighter1_247_369_Open_Image onclick="this.style.display='none'; Codehighlighter1_247_369_Open_Text.style.display='none'; Codehighlighter1_247_369_Closed_Image.style.display='inline'; Codehighlighter1_247_369_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_247_369_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_247_369_Closed_Text.style.display='none'; Codehighlighter1_247_369_Open_Image.style.display='inline'; Codehighlighter1_247_369_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_247_369_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_247_369_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;dispatch_read()<br><img id=Codehighlighter1_286_323_Open_Image onclick="this.style.display='none'; Codehighlighter1_286_323_Open_Text.style.display='none'; Codehighlighter1_286_323_Closed_Image.style.display='inline'; Codehighlighter1_286_323_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_286_323_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_286_323_Closed_Text.style.display='none'; Codehighlighter1_286_323_Open_Image.style.display='inline'; Codehighlighter1_286_323_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_286_323_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_286_323_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_handlerMgr</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">onRead();<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;HandlerManager&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">_handlerMgr;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;HandlerManager<br><img id=Codehighlighter1_395_634_Open_Image onclick="this.style.display='none'; Codehighlighter1_395_634_Open_Text.style.display='none'; Codehighlighter1_395_634_Closed_Image.style.display='inline'; Codehighlighter1_395_634_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_395_634_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_395_634_Closed_Text.style.display='none'; Codehighlighter1_395_634_Open_Image.style.display='inline'; Codehighlighter1_395_634_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_395_634_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_395_634_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;typedef&nbsp;std::list</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Handler</span><span style="COLOR: #000000">*&gt;</span><span style="COLOR: #000000">&nbsp;HandlerList;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onRead()<br><img id=Codehighlighter1_482_593_Open_Image onclick="this.style.display='none'; Codehighlighter1_482_593_Open_Text.style.display='none'; Codehighlighter1_482_593_Closed_Image.style.display='inline'; Codehighlighter1_482_593_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_482_593_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_482_593_Closed_Text.style.display='none'; Codehighlighter1_482_593_Open_Image.style.display='inline'; Codehighlighter1_482_593_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_482_593_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_482_593_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;notify&nbsp;all&nbsp;the&nbsp;handlers.</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;std::for_each(&nbsp;_handlers.begin(),&nbsp;_handlers.end(),&nbsp;onRead&nbsp;);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">private</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;HandlerList&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">_handlers;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Handler<br><img id=Codehighlighter1_653_694_Open_Image onclick="this.style.display='none'; Codehighlighter1_653_694_Open_Text.style.display='none'; Codehighlighter1_653_694_Closed_Image.style.display='inline'; Codehighlighter1_653_694_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_653_694_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_653_694_Closed_Text.style.display='none'; Codehighlighter1_653_694_Open_Image.style.display='inline'; Codehighlighter1_653_694_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_653_694_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_653_694_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">virtual</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onRead()&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;application&nbsp;level&nbsp;handler.</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;MyHandler&nbsp;:&nbsp;</span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">&nbsp;Handler<br><img id=Codehighlighter1_762_815_Open_Image onclick="this.style.display='none'; Codehighlighter1_762_815_Open_Text.style.display='none'; Codehighlighter1_762_815_Closed_Image.style.display='inline'; Codehighlighter1_762_815_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_762_815_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_762_815_Closed_Text.style.display='none'; Codehighlighter1_762_815_Open_Image.style.display='inline'; Codehighlighter1_762_815_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span id=Codehighlighter1_762_815_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_762_815_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top></span><span style="COLOR: #0000ff">public</span><span style="COLOR: #000000">:<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">&nbsp;onRead()&nbsp;<br><img id=Codehighlighter1_795_813_Open_Image onclick="this.style.display='none'; Codehighlighter1_795_813_Open_Text.style.display='none'; Codehighlighter1_795_813_Closed_Image.style.display='inline'; Codehighlighter1_795_813_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_795_813_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_795_813_Closed_Text.style.display='none'; Codehighlighter1_795_813_Open_Image.style.display='inline'; Codehighlighter1_795_813_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_795_813_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_795_813_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;</span><span style="COLOR: #008000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000"><br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span><span style="COLOR: #000000">;&nbsp;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>Reactor通过某种变形，可以将其改装为Proactor，在某些不支持异步IO的系统上，也可以隐藏底层的实现，利于编写跨平台<br>代码。我们只需要在dispatch(也就是demultiplexor)中封装同步IO操作的代码，在上层，用户提交自己的缓冲区到这一层，<br>这一层检查到设备可操作时，不像原来立即回调handler，而是开始IO操作，然后将操作结果放到用户缓冲区(读)，然后再<br>回调handler。这样，对于上层handler而言，就像是proactor一样。详细技法参见<a href="http://www.artima.com/articles/io_design_patterns2.html" target=_blank>这篇文章</a>。 </font>
<p><font size=2>其实就设计模式而言，我个人觉得某个模式其实是没有完全固定的结构的。不能说某个模式里就肯定会有某个类，类之间的<br>关系就肯定是这样。在实际写程序过程中也很少去特别地实现某个模式，只能说模式会给你更多更好的架构方案。 </font>
<p><font size=2>最近在看spserver的代码，看到别人提各种并发系统中的模式，有点眼红，于是才来扫扫盲。知道什么是<a href="http://www.cppblog.com/kevinlynx/archive/2008/06/04/52127.html" target=_blank>leader follower模式</a>，<br>reactor, proactor，multiplexing，对于心中的那个网络库也越来越清晰。 </font>
<p><font size=2>最近还干了些离谱的事，写了传说中的字节流编码，用模板的方式实现，不但保持了扩展性，还少写很多代码；处于效率考虑，<br>写了个static array容器(其实就是template &lt;typename _Tp, std::size_t size&gt; class static_array { _Tp _con[size])，<br>加了iterator，遵循STL标准，可以结合进STL的各个generic algorithm用，自我感觉不错。基础模块搭建完毕，解析了公司<br>服务器网络模块的消息，我是不是真的打算用自己的网络模块重写我的验证服务器？在另一个给公司写的工具里，因为实在厌恶<br>越来越多的重复代码，索性写了几个宏，还真的做到了代码的自动生成:D。 </font>
<p><font size=2>对优雅代码的追求真的成了种癖好.&nbsp; = =| </font></p>
<img src ="http://www.cppblog.com/kevinlynx/aggbug/52356.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kevinlynx/" target="_blank">Kevin Lynx</a> 2008-06-06 13:25 <a href="http://www.cppblog.com/kevinlynx/archive/2008/06/06/52356.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>半同步半异步模式以及Leader_Follwer模式</title><link>http://www.cppblog.com/kevinlynx/archive/2008/06/04/52127.html</link><dc:creator>Kevin Lynx</dc:creator><author>Kevin Lynx</author><pubDate>Wed, 04 Jun 2008 02:40:00 GMT</pubDate><guid>http://www.cppblog.com/kevinlynx/archive/2008/06/04/52127.html</guid><wfw:comment>http://www.cppblog.com/kevinlynx/comments/52127.html</wfw:comment><comments>http://www.cppblog.com/kevinlynx/archive/2008/06/04/52127.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/kevinlynx/comments/commentRss/52127.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/kevinlynx/services/trackbacks/52127.html</trackback:ping><description><![CDATA[<p><font size="2">这里提到的两个设计模式都是用于高并发系统(例如一个高性能的网络服务器)的。这里我只是简单地提一下： </font> <p><font size="2"><strong>1.</strong><a href="http://www.cppblog.com/Files/kevinlynx/hh_lf.rar" target="_blank"><strong>半同步/半异步（half-sync/half-async</strong></a><strong>）：</strong> </font> <p><font size="2">在网<a href="http://www.javaeye.com/topic/60414" target="_blank">上一份资料</a>中引用了一本貌似很<a href="http://www.china-pub.com/14109" target="_blank">经典的书</a>里的比喻：<br>” <br>许多餐厅使用 半同步/半异步 模式的变体。例如，餐厅常常雇佣一个领班负责迎接顾客，并在餐厅繁忙时留意给顾客安排桌位，<br>为等待就餐的顾客按序排队是必要的。领班由所有顾客“共享”，不能被任何特定顾客占用太多时间。当顾客在一张桌子入坐后，<br>有一个侍应生专门为这张桌子服务。 <br>“ </font> <p><font size="2">按照另一份似乎比较权威的文档的描述，要实现半同步/半异步模式，需要实现三层：异步层、同步层、队列层。因为很多操作<br>采用异步方式会比较有效率(例如高效率的网络模型似乎都采用异步IO)，但是异步操作的复杂度比较高，不利于编程。而同步<br>操作相对之下编程要简单点。为了结合两者的优点，就提出了这个模式。而为了让异步层和同步层互相通信(模块间的通信)，系<br>统需要加入一个通信队列。异步层将操作结果放入队列，同步层从队列里获取操作结果。 </font> <p><font size="2">回过头来看看我之前写的那个select网络模型代码，个人认为基本上算是一个半同步半异步模式的简单例子：Buffer相当于通信<br>队列，网络底层将数据写入Buffer，上层再同步地从该队列里获取出数据。这样看来似乎也没什么难度。 = = </font> <p>关于例子代码，直接引用iunknown给的：  <p>//这就是一个典型的循环队列的定义，iget 是队列头，iput 是队列尾&lt;/STRONG&gt;&nbsp;&nbsp; <br>int clifd[MAXNCLI], iget, iput;&nbsp;&nbsp;&nbsp; <br>int main( int argc, char * argv[] )&nbsp;&nbsp; <br>{&nbsp;&nbsp; <br>&nbsp; ......&nbsp;&nbsp; <br>&nbsp; int listenfd = Tcp_listen( NULL, argv[ 1 ], &amp;addrlen );&nbsp;&nbsp; <br>&nbsp; ......&nbsp;&nbsp; <br>&nbsp; iget = iput = 0;&nbsp;&nbsp; <br>&nbsp; for( int i = 0; i &lt; nthreads; i++ ) {&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; pthread_create( &amp;tptr[i].thread_tid, NULL, &amp;thread_main, (void*)i );&nbsp;&nbsp; <br>&nbsp; for( ; ; ) {&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; connfd = accept( listenfd, cliaddr,, &amp;clilen );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; clifd[ iput ] = connfd;&nbsp;&nbsp;&nbsp;&nbsp; // 接受到的连接句柄放入队列&lt;/STRONG&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if( ++iput == MAXNCLI ) iput = 0;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp; <br>}&nbsp;&nbsp; <br>void * thread_main( void * arg )&nbsp;&nbsp; <br>{&nbsp;&nbsp; <br>&nbsp; for( ; ; ) {&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; while( iget == iput ) pthread_cond_wait( ...... );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; connfd = clifd[ iget ];&nbsp;&nbsp;&nbsp;&nbsp; // 从队列中获得连接句柄&lt;/STRONG&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; if( ++iget == MAXNCLI ) iget = 0;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; web_child( connfd );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; close( connfd );&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp; <br>}&nbsp; <p><font size="2"><strong>2</strong><a href="http://www.cppblog.com/Files/kevinlynx/hh_lf.rar" target="_blank"><strong>.领导者/追随者（Leader/Followers）：</strong></a> </font> <p><font size="2">同样，给出别人引用的比喻：<br>”<br>在日常生活中，领导者/追随者模式用于管理许多飞机场出租车候车台。在该用例中，出租车扮演“线程”角色，排在第一辆的出<br>租车成为领导者，剩下的出租车成为追随者。同样，到达出租车候车台的乘客构成了必须被多路分解给出租车的事件，一般以先进<br>先出排序。一般来说，如果任何出租车可以为任何顾客服务，该场景就主要相当于非绑定句柄/线程关联。然而，如果仅仅是某些<br>出租车可以为某些乘客服务，该场景就相当于绑定句柄/线程关联。 <br>“ </font> <p><font size="2">其实这个更简单，我记得&lt;unix网络编程&gt;中似乎提到过这个。总之有一种网络模型(connection-per-thread?)里，一个线程用于<br>accept连接。当接收到一个新的连接时，这个线程就转为connection thread，而这个线程后面的线程则上升为accept线程。这里，<br>accept线程就相当于领导者线程，而其他线程则属于追随者线程。 </font> <p>iunknown 的例子代码：  <p>int listenfd;&nbsp;&nbsp; <br>int main( int argc, char * argv[] )&nbsp;&nbsp; <br>{&nbsp;&nbsp; <br>&nbsp; ......&nbsp;&nbsp; <br>&nbsp; listenfd = Tcp_listen( NULL, argv[ 1 ], &amp;addrlen );&nbsp;&nbsp; <br>&nbsp; ......&nbsp;&nbsp; <br>&nbsp; for( int i = 0; i &lt; nthreads; i++ ){&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; pthread_create( &amp;tptr[i].thread_tid, NULL, &amp;thread_main, (void*)i );&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp; <br>&nbsp; ......&nbsp;&nbsp; <br>}&nbsp;&nbsp; <br>void * thread_main( void * arg )&nbsp;&nbsp; <br>{&nbsp;&nbsp; <br>&nbsp; for( ; ; ){&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; // 多个线程同时阻塞在这个 accept 调用上，依靠操作系统的队列&lt;/STRONG&gt;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; connfd = accept( listenfd, cliaddr, &amp;clilen );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; web_child( connfd );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; close( connfd );&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; ......&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp; <br>}&nbsp; <p><font size="2"></font></p><img src ="http://www.cppblog.com/kevinlynx/aggbug/52127.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/kevinlynx/" target="_blank">Kevin Lynx</a> 2008-06-04 10:40 <a href="http://www.cppblog.com/kevinlynx/archive/2008/06/04/52127.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>