??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产精品热久久,九九久久99综合一区二区,91精品国产乱码久久久久久http://www.shnenglu.com/true/category/3800.htmlzh-cnWed, 12 Jan 2011 18:03:53 GMTWed, 12 Jan 2011 18:03:53 GMT60Buffercd应该单,直观http://www.shnenglu.com/true/archive/2011/01/13/138422.htmltruetrueWed, 12 Jan 2011 16:51:00 GMThttp://www.shnenglu.com/true/archive/2011/01/13/138422.htmlhttp://www.shnenglu.com/true/comments/138422.htmlhttp://www.shnenglu.com/true/archive/2011/01/13/138422.html#Feedback0http://www.shnenglu.com/true/comments/commentRss/138422.htmlhttp://www.shnenglu.com/true/services/trackbacks/138422.html阅读全文

true 2011-01-13 00:51 发表评论
]]>
ACE中简易的序列化机Ӟ(x)ACE_OutputCDR/ACE_InputCDRhttp://www.shnenglu.com/true/archive/2010/12/26/137484.htmltruetrueSun, 26 Dec 2010 01:52:00 GMThttp://www.shnenglu.com/true/archive/2010/12/26/137484.htmlhttp://www.shnenglu.com/true/comments/137484.htmlhttp://www.shnenglu.com/true/archive/2010/12/26/137484.html#Feedback2http://www.shnenglu.com/true/comments/commentRss/137484.htmlhttp://www.shnenglu.com/true/services/trackbacks/137484.html
#include <iostream>
#include 
<string>
#include 
<ace/OS.h>
#include 
<ace/String_Base.h>
#include 
<ace/CDR_Stream.h>
using namespace std;
#pragma comment(lib,
"aced")

int main(int argc, char* argv[])
{
    cout 
<< "ACE CDR demo" << endl;

    ACE_CString sAppName 
= "CDRDemo",sAppName2;
    ACE_CDR::Long nUID 
= 123456,nUID2;
    ACE_CDR::Float nfPosX 
= 120.51,nfPosX2;
    ACE_CDR::Double ndScore 
= 120.51,ndScore2;
    ACE_CString sDummy 
= "another string",sDummy2;
    ACE_CDR::Short  nsLength 
= 10,nsLength2;

    ACE_OutputCDR outCDR(ACE_DEFAULT_CDR_BUFSIZE);    
    
    outCDR 
<< nUID;
    outCDR 
<< nfPosX;
    outCDR 
<< ndScore;
    outCDR 
<< sAppName;//写字W串Ӟ先写入字W串的长?/span>
    outCDR << sDummy;
    outCDR 
<< nsLength;

    cout 
<< "OutputCDR size = " << outCDR.length() << endl;

    
//可以通过socket发送出?而在服务端进行下面的解析
    
//1.ACE_Message_Block *ACE_OutputCDR::begin (void)
    
//2.通过ACE_SOCK_Stream发送出?nbsp;   

    ACE_InputCDR inCDR(outCDR);

    inCDR 
>> nUID2;
    inCDR 
>> nfPosX2;
    inCDR 
>> ndScore2;
    inCDR 
>> sAppName2;
    inCDR 
>> sDummy2;
    inCDR 
>> nsLength2;
        

    ACE_ASSERT(nUID 
== nUID2);
    ACE_ASSERT(nfPosX 
== nfPosX2);
    ACE_ASSERT(ndScore 
== ndScore2);
    ACE_ASSERT(sAppName 
== sAppName2);
    ACE_ASSERT(sDummy 
== sDummy2);
    ACE_ASSERT(nsLength 
== nsLength2);

    cout 
<< "test ok." << endl;

    
return 0;
}

假若有如下的demo.idl,内容如下Q?br>
      struct user_info
      {
            int user_id;
            string user_name;            
      }
利用idl_gen生成代码Ӟ(x)
      (1)如果是R入式的方案,则生成user_infocLQ自动添加成员OutputCDR和InputCDR成员Qƈdpack(ACE_Message_Block &* msg)和parse(ACE_Message_Block * msg)成员函数Q在pack和parse里面Q调到对于的CDRc,按照cM数据成员的声明顺序依ơ序列化Q反序列?br>      (2)如果是非侵入式方案,则生成user_infocLQ生成独立函数的pack(user_info& info, ACE_Message_Block &* msg)和parse(user_info& info,ACE_Message_Block * msg),pack和parse的函数实现同?br>

true 2010-12-26 09:52 发表评论
]]>
ACE_Get_Opt解析命o(h)行参?/title><link>http://www.shnenglu.com/true/archive/2010/11/09/133131.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Tue, 09 Nov 2010 15:53:00 GMT</pubDate><guid>http://www.shnenglu.com/true/archive/2010/11/09/133131.html</guid><wfw:comment>http://www.shnenglu.com/true/comments/133131.html</wfw:comment><comments>http://www.shnenglu.com/true/archive/2010/11/09/133131.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/true/comments/commentRss/133131.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/true/services/trackbacks/133131.html</trackback:ping><description><![CDATA[     摘要: ACE ACE_Get_Opt 命o(h)?nbsp; <a href='http://www.shnenglu.com/true/archive/2010/11/09/133131.html'>阅读全文</a><img src ="http://www.shnenglu.com/true/aggbug/133131.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/true/" target="_blank">true</a> 2010-11-09 23:53 <a href="http://www.shnenglu.com/true/archive/2010/11/09/133131.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE_Thread_Mutex一个不跨^台的地方http://www.shnenglu.com/true/archive/2010/10/23/131009.htmltruetrueSat, 23 Oct 2010 13:44:00 GMThttp://www.shnenglu.com/true/archive/2010/10/23/131009.htmlhttp://www.shnenglu.com/true/comments/131009.htmlhttp://www.shnenglu.com/true/archive/2010/10/23/131009.html#Feedback0http://www.shnenglu.com/true/comments/commentRss/131009.htmlhttp://www.shnenglu.com/true/services/trackbacks/131009.htmlACE_Thread_Mutex的成员, int acquire (ACE_Time_Value *tv);在windows下是不支持的Q有些出人意料,之前一直没用过q个参数Q今天造轮子,参考ace发现的?/p>

true 2010-10-23 21:44 发表评论
]]>
仿照system v消息队列的内存消息队?/title><link>http://www.shnenglu.com/true/archive/2010/09/19/127031.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sat, 18 Sep 2010 17:01:00 GMT</pubDate><guid>http://www.shnenglu.com/true/archive/2010/09/19/127031.html</guid><wfw:comment>http://www.shnenglu.com/true/comments/127031.html</wfw:comment><comments>http://www.shnenglu.com/true/archive/2010/09/19/127031.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/true/comments/commentRss/127031.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/true/services/trackbacks/127031.html</trackback:ping><description><![CDATA[     摘要: 内存消息队列是服务器端常用的基础lgQ他使得W合生?消费者模型的两个U程或两l线E之间的通讯看v来更加清?nbsp; <a href='http://www.shnenglu.com/true/archive/2010/09/19/127031.html'>阅读全文</a><img src ="http://www.shnenglu.com/true/aggbug/127031.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/true/" target="_blank">true</a> 2010-09-19 01:01 <a href="http://www.shnenglu.com/true/archive/2010/09/19/127031.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ace中常用类的用D例(不断补充Q?/title><link>http://www.shnenglu.com/true/archive/2008/04/13/46983.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sun, 13 Apr 2008 08:32:00 GMT</pubDate><guid>http://www.shnenglu.com/true/archive/2008/04/13/46983.html</guid><wfw:comment>http://www.shnenglu.com/true/comments/46983.html</wfw:comment><comments>http://www.shnenglu.com/true/archive/2008/04/13/46983.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/true/comments/commentRss/46983.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/true/services/trackbacks/46983.html</trackback:ping><description><![CDATA[<p>#include "ace/Task.h"<br>#include <ace/Manual_Event.h><br>#include <ace/Auto_Event.h><br>#include "ace/OS.h"<br>#include <ace/Date_Time.h><br>#include <iostream></p> <p>using namespace std;<br>#pragma comment(lib,"aced")</p> <p>/**<br>* if MANUAL reset<br>*    sleep till the event becomes signaled<br>*    event remains signaled after wait() completes.<br>* else AUTO reset<br>*    sleep till the event becomes signaled<br>*    event resets wait() completes.<br>*/<br>//ACE_Manual_Event mevent;<br>ACE_Auto_Event   auto_event;<br>class TaskTest : public ACE_Task_Base<br>{<br>public:<br> int svc()<br> {<br>  cout << "task base test" << endl;<br>  ACE_Date_Time dt;<br>  cout << "y = " << dt.year() << endl;<br>  cout << "m = " << dt.month() << endl;<br>  cout << "s = " << dt.second() << endl;<br>  ACE_OS::sleep(2);<br>  //mevent.signal();<br>  auto_event.signal();<br>  return 0;<br> }<br>protected:<br>private:<br>};<br>int main(int argc, char* argv[])<br>{<br> TaskTest tt;<br> tt.activate();<br> //mevent.wait();<br> auto_event.wait();<br> tt.wait();<br> return 0;<br>}<br></p> <img src ="http://www.shnenglu.com/true/aggbug/46983.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/true/" target="_blank">true</a> 2008-04-13 16:32 <a href="http://www.shnenglu.com/true/archive/2008/04/13/46983.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE在Linux环境下的~译安装[转]http://www.shnenglu.com/true/archive/2007/07/15/28065.htmltruetrueSun, 15 Jul 2007 05:06:00 GMThttp://www.shnenglu.com/true/archive/2007/07/15/28065.htmlhttp://www.shnenglu.com/true/comments/28065.htmlhttp://www.shnenglu.com/true/archive/2007/07/15/28065.html#Feedback1http://www.shnenglu.com/true/comments/commentRss/28065.htmlhttp://www.shnenglu.com/true/services/trackbacks/28065.html                [Author by Jet Yan in April 4,2005]

W一?讄ACE_ROOT环境变量
Q?Qexport ACE_ROOT=/home/jet/ACE_wrappers
export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH

Q?Q或者直接在用户目录下编?bashrc文gQ内容如下:(x)
ACE_ROOT=/home/jet/ACE_wrappers
export ACE_ROOT
LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
然后重新登陆

Q?Q另一U方法是修改pȝ?etc/profile文gQ不q这栯是以用户变量?br>优先讄Q即如果已经按照上面的两U方法进行了讄Q那么以下的讄不
?x)被pȝ采用。)
“vi /etc/profile”
在其中加??br>ACE_ROOT=/opt/ACE
export ACE_ROOT
LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
我是加在“export PATH USER….”后的。完成后?etc/profile执行一ơ,命o(h)Q?br>“chmod 555 /etc/profile”
“/etc/profile”
q样我们的ACE_ROOTp|好了,可以用如下命令查看ACE_ROOT是否讄好了Q?br>“echo $ACE_ROOT”
q个时候最好reboot启动一ơlinux?br>-------------------------------------------------------------------

W二?解压出ACE-install.sh文gq修?br>Q?Q在/home/jet下徏立子目录ACEInstallQ将ACE.tar.gz上传臌目录

Q?Q从ACE.tar.gz解压出单个文件ACE-install.shQ?br>tar –zxvf ACE.tar.gz ACE_wrappers/ACE-install.sh

Q?QACE-install.sh攑֜哪个目录下无所谓,因ؓ(f)安装目录是由刚才讑֮?ACE_ROOT军_的?br>
Q?Qvi ACE-install.sh
我们可以看到~省的,q个文g是用来在UNIX下做安装的。所以我们要其中的?br>关UNIX的部分换成linux卛_?br>“MY_ACEDIR=${HOME}/aceconfig” -->> “MY_ACEDIR=/home/my/ACE”
“MY_ACE_CONFIG=config-sunos5.4-sunc++-4.x.h” -->> “MY_ACE_CONFIG=config-linux.h”
“MY_ACE_GNU_MACROS=platform_sunos5_sunc++.GNU” -->> “MY_ACE_GNU_MACROS=platform_linux.GNU”
好了Q文件修改完毕,保存退?#8220;:wq”?br>-------------------------------------------------------------------

W三?q行ACE-install.shQshell脚本Q安装ACE
Q?Q当前目?home/jet/ACEInstall/ACE_wrappers

Q?Q修改ACE-install.sh的属性,使其可执?br>chmod 777 ACE-install.sh

Q?Q执行:(x)
./ACE-install.sh
此后是较长旉的解包、编译等待时间。这个过E将不会(x)出现M错误Q因为安装脚?br>ؓ(f)我们做很多事情,如:(x)生成config.hQ生成platform_macros.GNU。(即出现删除
文g的错误,对结果应该没有媄(jing)响,遇到q种情况要具体分析一下。)
因此׃需要按ACE-install.html中说的那h工做如下改动Q?br>  ?ACE_ROOT/ace目录?
  ln -s config-linux.h config.h
  ?ACE_ROOT/include/makeinclude/目录?
  ln -s platform_linux.GNU platform_macros.GNU
QWindows中没有文件连接这一_(d)所以要自己生成一个config.h文gQ再在它的里面加一
句话“#include "ace/config-win32.h"”。)

Q?Q如果编译中出现错误Q如“../apps/gperf”{,L(fng)?ACE_ROOT/apps下的MakefileQ?br>其中的有关“gperf”的部分注释掉Q这个东西只是一个例子,可以不去~译它?br>一下,用ACE-install.sh来安装,?x)编译ACE、tests、apps{?br>最后会(x)生成libACE.so?qing)tests、apps下也?x)出来很多经q编译的文g?br>当然如果你只是下载了ACE.tar.gzq样的单个包来安装,你可以手工改文gQ再makeQ?br>因ؓ(f)只编译ACEQ工作就了很多Q手工做q可以接受?br>
Q?Q编译过E日志放?tmp/myacemaker.err
-------------------------------------------------------------------

W四?直接试ACE提供的例?br>Q?Q在$ACE_ROOT/examples/Synch中,修改proc_sema.cpp文g如下Q?br>#include "ace/OS_NS_stdio.h"
在main函数?br>ACE_OS::printf("Hello,World! \n");

Q?Q执行makeQOK后运行?br>
Q?Q如果运行时装在不到share objectQ可能是lib路径问题Q因?so文g是程序运行过E中
装蝲的,不是在编译的时候,因此要设|LD_LIBRARY_PATHQ?br>[jet@S]$ export LD_LIBRARY_PATH=/home/jet/ACE_wrappers/lib:$LD_LIBRARY_PATH
-------------------------------------------------------------------

W五?写一个简单的E序试一下ACE
Q?Q在/home/jet/下新建ACETest子目录,写好E序如client.cppQ上传到该目?br>
Q?Q拷贝第四步的那个Makefile文g到该目录Qƈ做如下修?br>修改其中输出文g?#8220;BIN = hello”Qƈ修改“
.obj/proc_sema.o .obj/proc_sema.so .shobj/proc_sema.o .shobj/proc_sema.so: proc_sema.cpp \”
中后面的“proc_sema.cpp”?#8220;client.cpp”?br>好,我们可以~译一个我们自qACEE序了,make卛_。应该能通过Q生成执行文件clientQ?br>大小大约?12Kb。运行之Q?#8220;./client”?br>-------------------------------------------------------------------

=================================================
另一U更为直接的安装Ҏ(gu)Q?br>
步骤1Q设|环境变?br>export ACE_ROOT=/home/jet/ACE_wrappers
export LD_LIBRARY_PATH=$ACE_ROOT/ace:$LD_LIBRARY_PATH
也可以直接修?bashrc文gQ以免退出后讄的这些变量消?br>
[env][echo $ACE_ROOT]

步骤2Q?br>针对不同版本创徏两个文g链接:
  ?ACE_ROOT/ace目录?
  ln -s config-linux.h config.h
  ?ACE_ROOT/include/makeinclude/目录?
  ln -s platform_linux.GNU platform_macros.GNU

步骤3Q?br>?ACE_ROOT目录下,新徏一个目录,用以执行configure的结?br>  mkdir aaa
  cd aaa
?ACE_ROOT/aaa中运?br>  ../configure
在确认结果无误后Q执?
  make
OKQ?br>


[rm -f -r *]删除目录下所有的文g和子目录-f是强制force删除Q?r是代表目录也删除

[ldd 可执行文件] 昄该文件运行时候需要的动态链接库

[ipcs] 昄pȝ的共享内存、信号量、消息队列的情况 ipc show
[ipcrm <shm| msg| sem> id]



true 2007-07-15 13:06 发表评论
]]>
ACE关于文g的操?/title><link>http://www.shnenglu.com/true/archive/2007/06/09/25911.html</link><dc:creator>true</dc:creator><author>true</author><pubDate>Sat, 09 Jun 2007 10:30:00 GMT</pubDate><guid>http://www.shnenglu.com/true/archive/2007/06/09/25911.html</guid><wfw:comment>http://www.shnenglu.com/true/comments/25911.html</wfw:comment><comments>http://www.shnenglu.com/true/archive/2007/06/09/25911.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/true/comments/commentRss/25911.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/true/services/trackbacks/25911.html</trackback:ping><description><![CDATA[ ACE_FILE_Addr file_addr;<br> file_addr.set("log.txt");<br> ACE_FILE_IO file;<br> ACE_FILE_Connector file_connector;<br> if (file_connector.connect(file,<br>        file_addr,<br>        0,<br>        ACE_Addr::sap_any,<br>        0,<br>        O_RDWR|O_CREAT|O_APPEND<br>        ) == -1)<br> {<br>  cout << "error" << endl;<br> } <img src ="http://www.shnenglu.com/true/aggbug/25911.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/true/" target="_blank">true</a> 2007-06-09 18:30 <a href="http://www.shnenglu.com/true/archive/2007/06/09/25911.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ACE_NT_ServiceQWINDOWShttp://www.shnenglu.com/true/archive/2007/04/24/22741.htmltruetrueTue, 24 Apr 2007 09:55:00 GMThttp://www.shnenglu.com/true/archive/2007/04/24/22741.htmlhttp://www.shnenglu.com/true/comments/22741.htmlhttp://www.shnenglu.com/true/archive/2007/04/24/22741.html#Feedback1http://www.shnenglu.com/true/comments/commentRss/22741.htmlhttp://www.shnenglu.com/true/services/trackbacks/22741.htmlACE_NT_ServiceQWINDOWSQ?br>本h的观点,SERVICE是WINDOWS版的DAEMON?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">ACE_NT_Service通过包装一整套WINDOWS提供的SERVICE API定义了一个控制NT SERVICE的接口。应用程序承该接口可以实现和UNIX上DAEMON怼的功能。下面先单描qWINDOWSSERVICEE序框架Q再详细描述c?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">ACE_NT_Service对WINDOWS SERVICEE序框架的包装?br>
WINDOWS SERVICE
一个完整的NT SERVICEE序应该包含以下四部分:(x)
1.控制台应用程序的main函数
2.SERVICE入口函数ServiceMain
3.SERVICE CONTROL HANDLERQSCM利用该函数和SERVICE通信q控制程序的起停?br>4.SERVICE安装和卸载器

ServiceMain和Service Control Handler
首先我们来讨论ServiceMain和Service Control Handler。WINDOWS规定每个SERVICE都拥有自q立的ServiceMain以及(qing)Service Control Handler函数。主E序调用StartServiceCtrlDispatcherӞW(xu)INDOWS为每个SERVICE创徏一个线E,q且在新U程中运行ServiceMain函数。SCM利用Service Control Handler函数和SERVICEE序通信Q用h行startQstopQpause以及(qing)continue{操作时QSCM通过Service Control Handler函数来控制SERVICE的行为。Service Control Handler函数基本上会(x)包含一个switch语句来处理每U情c(din)?br>
安装/卸蝲SERVICE
WINDOWS提供一些API来安?卸蝲SERVICEQ这h们就可以不用注册函数就能在pȝ中注册这些节炏V这些API分别是CreateService和DeleteService。要安装SERVICEQ需要先利用函数OpenSCManager打开SCM数据库,接着利用SERVICE的二q制文g路径调用CreateServiceQ在调用CreateService旉要ؓ(f)SERVICE指定名称Q原因是使用DeleteService删除服务旉要利用该标识?br>
ACE_NT_Service
查看ACE源码Q其中和c?ACE_NT_Service实现密切相关的的文g有NT_Service.cpp、NT_Service.h、NT_Service.i?br>
ACE_NT_Service中的ServiceMain和Service Control Handler
ServiceMain和Service Control Handler定义h固定模式Q?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">ACE_NT_Service提供?define ACE_NT_SERVICE_DEFINE(SVCNAME, SVCCLASS, SVCDESC)用于化定义。具体的宏定义可以参考ACE代码Q这里不再列出,q里只分析相关的c?strong style="COLOR: black; BACKGROUND-COLOR: #ffff66">ACE_NT_Service的成员函数handle_control,init,open,wait和fini。函数handle_control被用于响应SERVICE DISPATCHERh,其必dSVC函数交互以媄(jing)响请求控制操作。缺省实现包括SERVICE_CONTROL_STOPQSERVICE_CONTROL_PAUSEQSERVICE_CONTROL_CONTINUEQSERVICE_CONTROL_INTERROGATEQSERVICE_CONTROL_SHUTDOWN?br>
函数handle_control的部分关键代码解?br>/* 调用stop_requested响应关闭操作 */
case SERVICE_CONTROL_SHUTDOWN:
case SERVICE_CONTROL_STOP:
this->stop_requested (control_code);
break;
/* 调用pause_requested响应挂v操作 */
case SERVICE_CONTROL_PAUSE:
this->pause_requested (control_code);
break;
/* 调用continue_requested响应挂v后启动操?*/
case SERVICE_CONTROL_CONTINUE:
this->continue_requested (control_code);
break;
/* 调用interrogate_requested报告当前状?/
case SERVICE_CONTROL_INTERROGATE:
this->interrogate_requested (control_code);
break;

函数open 的部分关键代码解?br>/* 报告状?*/
this->report_status (SERVICE_START_PENDING, 0);
/* 执行用户代码 */
int svc_return = this->svc ();

函数fini 的部分关键代码解?br>/* 报告状?*/
return this->report_status (SERVICE_STOPPED, 0);

函数stop_requested的部分关键代码解?br>/* 报告状?*/
this->report_status (SERVICE_STOP_PENDING);

函数pause_requested的部分关键代码解?br>/* 报告状?*/
this->report_status (SERVICE_PAUSE_PENDING);
/* 挂v*/
this->suspend ();
/* 报告状?*/
this->report_status (SERVICE_PAUSED);

函数continue_requested的部分关键代码解?br>/* 报告状?*/
this->report_status (SERVICE_CONTINUE_PENDING);
/* 恢复*/
this->resume ();
/* 报告状?*/
this->report_status (SERVICE_RUNNING);

函数interrogate_requested的部分关键代码解?br>/* 报告状?*/
this->report_status (0);
安装/卸蝲SERVICE
ACE_NT_Service定义两个成员函数InsertQremove来安装(卸蝲QSERVICE。它们分别在内部调用WINDOWS API——CreateService以及(qing)DeleteService?

Insert函数的部分关键代码解?br>
/* 打开和host()上SCManager的通信 */
SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host ()Q?#8230;…);
/* 以名Uname() 创徏服务 */
SC_HANDLE sh = ACE_TEXT_CreateService (sc_mgr,this->name (),this->desc (),
SERVICE_ALL_ACCESS,this->svc_status_.dwServiceType,start_type,
error_control,exe_path,……);
/* 关闭和SCManager的通信 */
CloseServiceHandle (sc_mgr);
/* 关闭服务句柄Q重新写入新句柄 */
if (this->svc_sc_handle_ != 0)
CloseServiceHandle (this->svc_sc_handle_);
this->svc_sc_handle_ = sh;

Remove函数部分关键代码解析

/* 从SCM中删除insert创徏的服务句?*/
if (DeleteService (this->svc_sc_handle()) == 0
&& GetLastError () != ERROR_SERVICE_MARKED_FOR_DELETE)
控制SERVICE
ACE_NT_Service定义成员函数start_svc, stop_svc, pause_svc, continue_svc分别用于启动、停止、挂起和l箋服务?br>start_svc函数的部分关键代码解?br>
/* 启动服务 */
if (!ACE_TEXT_StartService (svc, argc, argv))
this->wait_for_service_state (SERVICE_RUNNING, wait_time);

stop_svc函数的部分关键代码解?br>
/* 关闭服务 */
if (!ControlService (svc, SERVICE_CONTROL_STOP, &this->svc_status_))
this->wait_for_service_state (SERVICE_STOPPED, wait_time);

pause_svc函数的部分关键代码解?br>
/* 吊v服务 */
if (!ControlService (svc, SERVICE_CONTROL_PAUSE,&this->svc_status_))
this->wait_for_service_state (SERVICE_PAUSED,wait_time);

continue_svc函数的部分关键代码解?br>
/* 挂起业务重新启?*/
if (!ControlService (svc,SERVICE_CONTROL_CONTINUE,&this->svc_status_))
this->wait_for_service_state (SERVICE_RUNNING,wait_time);

一些辅助函?br>svc_sc_handle部䆾关键代码解析

/* 打开SCM */
SC_HANDLE sc_mgr = ACE_TEXT_OpenSCManager (this->host (),……)
if (sc_mgr != 0)
{
/* 获取服务句柄 */
this->svc_sc_handle_ = ACE_TEXT_OpenService (sc_mgr,……)
/* 关闭SCM */
CloseServiceHandle (sc_mgr);
}
/* q回获取到的服务句柄 */
return this->svc_sc_handle_;

wait_for_service_state部䆾关键代码解析

/* 获取当前旉 */
ACE_Time_Value time_out = ACE_OS::gettimeofday ();
/* 加上{待旉 */
if (wait_time != 0) time_out += *wait_time;
// Poll until the service reaches the desired state.
for (;
{
/* 查询当前状?*/
service_ok = 0 != QueryServiceStatus (this->svc_sc_handle_, &this->svc_status_);
/* 如果已经到达指定状态,退出@?*/
if (desired_state == this->svc_status_.dwCurrentState) break;
/* 如果出指定旉Q退出@?*/
if (wait_time != 0 && ACE_OS::gettimeofday () > time_out )
{ ……
break;
}
/* 睡眠{待 */
::Sleep (this->svc_status_.dwWaitHint);
}

report_status部䆾关键代码解析
/* 告诉pȝ服务新的状?*/
SetServiceStatus (this->svc_handle_,&this->svc_status_) ? 0 : -1;

 

 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=748930



true 2007-04-24 17:55 发表评论
]]>
C10k[转]http://www.shnenglu.com/true/archive/2007/04/05/21283.htmltruetrueThu, 05 Apr 2007 01:00:00 GMThttp://www.shnenglu.com/true/archive/2007/04/05/21283.htmlhttp://www.shnenglu.com/true/comments/21283.htmlhttp://www.shnenglu.com/true/archive/2007/04/05/21283.html#Feedback0http://www.shnenglu.com/true/comments/commentRss/21283.htmlhttp://www.shnenglu.com/true/services/trackbacks/21283.html摘要


~写q接数巨大的高负载服务器E序Ӟl典的多U程模式和select模式都不再适用?
应当抛弃它们Q采用epoll/kqueue/dev_poll来捕获I/O事g。最后简要介l了AIO?


由来


|络服务在处理数以万计的客户端连接时Q往往出现效率低下甚至完全瘫痪Q这被称?
C10K问题。随着互联|的q速发展,来多的网l服务开始面临C10K问题Q作为大?
|站的开发h员有必要对C10K问题有一定的了解。本文的主要参考文献是
<http://www.kegel.com/c10k.htmlhttp://www.kegel.com/c10k.htmls?

C10K问题的最大特Ҏ(gu)Q设计不够良好的E序Q其性能和连接数?qing)机器性能的关pd往
是非U性的。D个例子:(x)如果没有考虑qC10K问题Q一个经典的Zselect的程序能?
旧服务器上很好处?000q发的吞吐量Q它?倍性能新服务器上往往处理不了q发
2000的吞吐量?

q是因ؓ(f)在策略不当时Q大量操作的消耗和当前q接数n成线性相兟뀂会(x)D单个d
的资源消耗和当前q接数的关系?x)是O(n)。而服务程序需要同时对C万计的socketq?
行I/O处理Q积累下来的资源消耗会(x)相当可观Q这昄?x)导致系l吞吐量不能和机器?
能匹配。ؓ(f)解决q个问题Q必L变对q接提供服务的策略?


基本{略


主要有两斚w的策略:(x)1.应用软g以何U方式和操作pȝ合作Q获取I/O事gq调度多
个socket上的I/O操作Q?. 应用软g以何U方式处理Q务和U程/q程的关pR前者主
要有dI/O、非dI/O、异步I/Oq?U方案,后者主要有每Q?q程、每d1U?
E、单U程、多d׃nU程池以?qing)一些更复杂的变U方案。常用的l典{略如下Q?

1.         Serve one client with each thread/process, and use blocking I/O
q是程序和java常用的策略,对于交互式的长连接应用也是常见的选择(比如BBS)?
q种{略很能难高性能E序的需求,好处是实现极其简单,Ҏ(gu)嵌入复杂的交互?
辑。Apache、ftpd{都是这U工作模式?

2.         Serve many clients with single thread, and use nonblocking I/O
and readiness notification
q是l典模型Qdatapipe{程序都是如此实现的。优点在于实现较单,方便ULQ也
能提供够的性能Q缺点在于无法充分利用多CPU的机器。尤其是E序本n没有复杂?
业务逻辑时?

3.         Serve many clients with each thread, and use nonblocking I/O and
readiness notification
对经典模?的简单改q,~点是容易在多线Eƈ发上出bugQ甚x些OS不支持多U程
操作readiness notification?

4.         Serve many clients with each thread, and use asynchronous I/O
在有AI/O支持的OS上,能提供相当高的性能。不qAI/O~程模型和经典模型差别相?
大,基本上很隑ֆZ个框架同时支持AI/O和经典模型,降低了程序的可移植性。在
Windows上,q基本上是唯一的可选方案?

本文主要讨论模型2的细节,也就是在模型2下应用Y件如何处理Socket I/O?


select ?nbsp;poll


最原始的同步阻?nbsp;I/O 模型的典型流E如下:(x)

同步d I/O 模型的典型流E?

从应用程序的角度来说Qread 调用?x)gl很长时_(d)应用E序需要相当多U程来解?
q发讉K问题。同步非dI/OҎ(gu)有所改进Q?

l典的单U程服务器程序结构往往如下Q?


do {

         Get Readiness Notification of all sockets

         Dispatch ready handles to corresponding handlers

                   If (readable) {
                            read the socket

                            If (read done)

                                     Handler process the request
                   }

                   if (writable)

                            write response

                   if (nothing to do)

                            close socket

} while(True)

非阻?nbsp;I/O 模型的典型流E?

异步d I/O 模型的典型流E?

其中关键的部分是readiness notificationQ找出哪一个socket上面发生了I/O事g?
一般从教科书和例子E序中首先学到的是用select来实现。Select定义如下Q?


int select(int n, fd_set *rd_fds, fd_set *wr_fds, fd_set *ex_fds, struct
timeval *timeout);

Select用到了fd_setl构Q从man page里可以知道fd_set能容U的句柄和FD_SETSIZE?
兟뀂实际上fd_set?nix下是一个bit标志数组Q每个bit表示对应下标的fd是不是在
fd_set中。fd_set只能容纳~号于 FD_SETSIZE的那些句柄?

FD_SETSIZE默认?024Q如果向fd_set里放入过大的句柄Q数l越界以后程序就?x)?
掉。系l默认限制了一个进E最大的句柄号不过1024Q但是可以通过ulimit -n命o(h)
/setrlimit函数来扩大这一限制。如果不q怸个程序在FD_SETSIZE=1024的环境下~?
译,q行时又遇到ulimit –n > 1024的,那就只有求上帝保佑不会(x)垮掉了?/font>


在ACE环境中,ACE_Select_Reactor针对q一点特别作了保护措施,但是q是有recv_n
q样的函数间接的使用了selectQ这需要大家注意?

针对fd_set的问题,*nix提供了poll函数作ؓ(f)select的一个替代品。Poll的接口如下:(x)


int poll(struct pollfd *ufds, unsigned int nfds, int timeout);

W?个参数ufds是用h供的一个pollfd数组Q数l大由用户自行军_Q因此避免了
FD_SETSIZE带来的麻烦。Ufds是fd_set的一个完全替代品Q从select到poll的移植很?
ѝ到此ؓ(f)止,臛_我们面对C10KQ可以写Z个能work的程序了?

然而Select和Poll在连接数增加Ӟ性能急剧下降。这有两斚w的原因:(x)首先操作pȝ
面对每次的select/poll操作Q都需要重新徏立一个当前线E的兛_事g列表Qƈ把线
E挂在这个复杂的{待队列上,q是相当耗时的。其ơ,应用软g在select/pollq回
后也需要对传入的句柄列表做一ơ扫描来dispatchQ这也是很耗时的。这两g事都是和
q发数相养I而I/O事g的密度也和ƈ发数相关Q导致CPU占用率和q发数近似成O(n2)
的关pR?


epoll, kqueue, /dev/poll


因ؓ(f)以上的原因,*nix的hacker们开发了epoll, kqueue, /dev/pollq?套利器来帮助
大家Q让我们跪拜三分钟来感谢q些大神。其中epoll是linux的方案,kqueue?
freebsd的方案,/dev/poll是最古老的Solaris的方案,使用隑ֺ依次递增?

单的_(d)q些api做了两g事:(x)1.避免了每ơ调用select/poll时kernel分析参数建立
事g{待l构的开销Qkernell护一个长期的事gx列表Q应用程序通过句柄修改q?
个列表和捕获I/O事g?.避免了select/pollq回后,应用E序扫描整个句柄表的开
销QKernel直接q回具体的事件列表给应用E序?

在接触具体api之前Q先了解一下边~触?edge trigger)和条件触?level trigger)
的概c(din)边~触发是指每当状态变化时发生一个io事gQ条件触发是只要满条g发
生一个io事g。D个读socket的例子,假定l过长时间的沉默后,现在来了100个字
节,q时无论边缘触发和条件触发都?x)生一个read ready notification通知应用E?
序可诅R应用程序读?0个字节,然后重新调用api{待io事g。这时条件触发的api?
因ؓ(f)q有50个字节可M而立卌回用户一个read ready notification。而边~触?
的api?x)因为可读这个状态没有发生变化而陷入长期等待?

因此在用边~触发的apiӞ要注意每ơ都要读到socketq回EWOULDBLOCK为止Q否?
q个socketq废了。而用条件触发的apiӞ如果应用E序不需要写׃要关?
socket可写的事Ӟ否则׃(x)无限ơ的立即q回一个write ready notification。大?
常用的select是属于条g触发q一c,以前本hqq长期关注socket写事件从?
CPU 100%的毛病?

epoll的相兌用如下:(x)


int epoll_create(int size)


int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)


int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int
timeout)

epoll_create创徏kernel中的x事g表,相当于创建fd_set?

epoll_ctl修改q个表,相当于FD_SET{操?

epoll_wait{待I/O事g发生Q相当于select/poll函数

epoll完全是select/poll的升U版Q支持的事g完全一致。ƈ且epoll同时支持边缘?
发和条g触发Q一般来讲边~触发的性能要好一些。这里有个简单的例子Q?


struct epoll_event ev, *events;

int kdpfd = epoll_create(100);

ev.events = EPOLLIN | EPOLLET;  // 注意q个EPOLLETQ指定了边缘触发

ev.data.fd =listener;

epoll_ctl(kdpfd, EPOLL_CTL_ADD, listener, &ev);

for(;;) {

   nfds = epoll_wait(kdpfd, events, maxevents, -1);

 

   for(n = 0; n < nfds; ++n) {

       if(events[n].data.fd == listener) {

           client = accept(listener, (struct sockaddr *) &local,

                           &addrlen);

           if(client < 0){

               perror("accept");

               continue;

           }

           setnonblocking(client);

           ev.events = EPOLLIN | EPOLLET;

           ev.data.fd = client;

           if (epoll_ctl(kdpfd, EPOLL_CTL_ADD, client, &ev) < 0) {

               fprintf(stderr, "epoll set insertion error: fd=%d0,

                       client);

               return -1;

           }

       }

       else

           do_use_fd(events[n].data.fd);

   }

}

单介l一下kqueue?dev/poll

kqueue是freebsd的宠儿,kqueue实际上是一个功能相当丰富的kernel事g队列Q它?
仅仅是select/poll的升U,而且可以处理signal、目录结构变化、进E等多种事g?
Kqueue是边~触发的

/dev/poll是Solaris的物,是这一pd高性能API中最早出现的。Kernel提供一个特
D的讑֤文g/dev/poll。应用程序打开q个文g得到操纵fd_set的句柄,通过写入
pollfd来修改它Q一个特Dioctl调用用来替换select。由于出现的q代比较早,所?
/dev/poll的接口现在看上去比较W拙可笑?

C++开发:(x)ACE 5.5以上版本提供了ACE_Dev_Poll_Reactor装了epoll?dev/poll两种
apiQ需要分别在config.h中定义ACE_HAS_EPOLL和ACE_HAS_DEV_POLL来启用?

Java开发:(x) JDK 1.6的Selector提供了对epoll的支持,JDK1.4提供了对/dev/poll的支
持。只要选择_高的JDK版本p了?


异步I/O以及(qing)Windows


和经典模型不同,异步I/O提供了另一U思\。和传统的同步I/O不同Q异步I/O允许q?
E发起很?nbsp;I/O 操作Q而不用阻塞或{待M操作完成。稍后或在接收到 I/O 操作?
成的通知Ӟq程可以检?nbsp;I/O 操作的结果?

异步非阻?nbsp;I/O 模型是一U处理与 I/O 重叠q行的模型。读h?x)立卌回,说?
read h已经成功发v了。在后台完成L作时Q应用程序然后会(x)执行其他处理?
作。当 read 的响应到达时Q就?x)生一个信h执行一个基于线E的回调函数来完?
q次 I/O 处理q程。异步I/O 模型的典型流E:(x)

异步非阻?nbsp;I/O 模型的典型流E?

对于文g操作而言QAIO有一个附带的好处Q应用程序将多个l碎的磁盘请求ƈ发的?
交给操作pȝ后,操作pȝ有机?x)对q些hq行合ƈ和重新排序,q对同步调用而言
是不可能的——除非创建和h数目同样多的U程?

Linux Kernel 2.6提供了对AIO的有限支持——仅支持文gpȝ。libc也许能通过来线
E来模拟socket的AIOQ不q这Ҏ(gu)能没意义。ȝ来说Linux的aioq不成熟

Windows对AIO的支持很好,有IOCP队列和IPCP回调两种方式Q甚x供了用户U异步调
用APC功能。Windows下AIO是唯一可用的高性能Ҏ(gu)Q详情请参考MSDN 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1537545




true 2007-04-05 09:00 发表评论
]]>
在ACE中用epoll[zhuan]http://www.shnenglu.com/true/archive/2007/04/05/21281.htmltruetrueThu, 05 Apr 2007 00:32:00 GMThttp://www.shnenglu.com/true/archive/2007/04/05/21281.htmlhttp://www.shnenglu.com/true/comments/21281.htmlhttp://www.shnenglu.com/true/archive/2007/04/05/21281.html#Feedback0http://www.shnenglu.com/true/comments/commentRss/21281.htmlhttp://www.shnenglu.com/true/services/trackbacks/21281.html在ACE中用epoll
2007-01-18 15:56

星期? 六月 8th, 2006 

        很显Ӟ文章的标题决定了我们是在linux下用ACE。我们知道ACE在linux下缺省是用select来实现Reactor的,epoll相对于select的好处这里就不再啰嗦了,我们直接讲操作步?
    W一Q重新编译ACE?br>     ACE库中通过ACE_Dev_Poll_ReactorcL支持epoll,但是ACE库缺省的安装是没有编译这个类的,我们要做的就是将ACE_Dev_Poll_Reactor~译q接到ACE库中(faint,又要重新~译ACEQ在我那台破服务器上~译一ơ需要一个多时).我的操作pȝ是Redhat linux AS4.0,ACE的版本是5.4.10。根据ACE压羃包中的ACE-INSTALL.htmlQ我是用”Building ACE with GNU Autoconf“q种方式来安装的Q安装步骤如?很简?׃译?:
       1 cd to the top-level ACE_wrappers directory.

       2.Create a subdirectory to hold your build’s configuration and built ACE version,     and   then change to the new directory:

       mkdir build

       cd build

     

       3.Note that you do not run the create_ace_build.pl utility mentioned in the Cloning the Source Tree section. The configure script takes care of creating all files and links that are needed.

Configure ACE for your platform by issuing the following command: c

       ../configure [options]

     
      4.Build ACE by typing make.

      5. Install ACE by typing make install.
      好,现在l于可以讲如何将ACE_Dev_Poll_Reactor~译到ACE库中M。在上述的第一步和W二步之间修改ACE_wrappers/ace/config-linux.h,增加一行:(x)#define ACE_HAS_EVENT_POLLQ然后执行第2?步,W??./configure执行完之后,build目录下会(x)生成一些文件和目录Q打开ACE_wrappers/build/ace/config.h,增加一行:(x)#define ACE_HAS_EVENT_POLL。然后执行第4步make和第5步make install.OKQ在漫长的编译以后,支持epoll的ACE库ȝ完成了?/p>

     W二Q修改应用程?br>        应用E序修改很简单,两行代码搞掂,在应用程序初始化?必须是在W一ơ用ACE_Reactor::instance()之间)加入:
       
        m_pDevPollReactor=new ACE_Dev_Poll_Reactor;
       ACE_Reactor::instance(new ACE_Reactor(m_pDevPollReactor));
      
       那么在后l的对ACE_Reactor::instance()的调用就是用ACE_Dev_Poll_Reactor的实C?br>  
   W三Q重新编译应用程?br>  
        在应用程序的makefile中加?nbsp;-DACE_HAS_EVENT_POLL,重新make应用E序。OK,打完收工?br>        



true 2007-04-05 08:32 发表评论
]]>
պƷרþþ| Ʒһþ㽶߿ۿ| ݹƷþþþþ| ĻƷѾþ| þþƷɫ鶹| ëƬþþþþùëƬ | þþƷþ˼˼| ޹þþþƷС˵| þþþAVרJN | Ļ˾Ʒþò| þ㽶߿ۿ99| 91Ʒպþò| 91þþƷһëƬ| Ʒŷ޺ձþ | AþþƷ| þһձɫۺϾþ| 99ŷƷþþѿ | Ʒþþþþù| þþùҺ| ޾þˬ˾Ʒ | þþƷŷƬ| þˬˬAV| þþƷһ| þ| ŷպľþ| þþƷ| ޹ƷۺϾþ| vĻþ | þúݺɫۺ| һþöAV | Ʒþþþþø69| Ʒҹþ| ھƷþ| ŷ龫Ʒþþþ| þþȹ͵ۺ| ٸ޾þþþþ4| 99þҹɫƷվ| þù| ձƬҹþ| þþƷަvDz | ھƷþþĻ|