??xml version="1.0" encoding="utf-8" standalone="yes"?> 实时操作pȝ的一个特点就是,一个实时Q务,会在规定的时间内得到响应Qƈ且在规定的时间内完成d。所以,一切不可预知的动作都是有害的?/p> 有兴可以看看下面两个链接: Jump to: navigation, search In scheduling, priority inversion is the scenario where a low priority task holds a shared resource that is required by a high priority task. This causes the execution of the high priority task to be blocked until the low priority task has released the resource, effectively "inverting" the relative priorities of the two tasks. If some other medium priority task, one that does not depend on the shared resource, attempts to run in the interim, it will take precedence over both the low priority task and the high priority task. In some cases, priority inversion can occur without causing immediate harm—the delayed execution of the high priority task goes unnoticed, and eventually the low priority task releases the shared resource. However, there are also many situations in which priority inversion can cause serious problems. If the high priority task is left starved of the resources, it might lead to a system malfunction or the triggering of pre-defined corrective measures, such as a watch dog timer resetting the entire system. The trouble experienced by the Mars lander "Mars Pathfinder"[1][2] is a classic example of problems caused by priority inversion in realtime systems. Priority inversion can also reduce the perceived performance of the system. Low priority tasks usually have a low priority because it is not important for them to finish promptly (for example, they might be a batch job or another non-interactive activity). Similarly, a high priority task has a high priority because it is more likely to be subject to strict time constraints—it may be providing data to an interactive user, or acting subject to realtime response guarantees. Because priority inversion results in the execution of the low priority task blocking the high priority task, it can lead to reduced system responsiveness, or even the violation of response time guarantees. A similar problem called deadline interchange can occur within Earliest Deadline First Scheduling (EDF). The existence of this problem has been known since the 1970s, but there is no fool-proof method to predict the situation. There are however many existing solutions, of which the most common ones are: .操作pȝ要求Q?br> - Windows 2000, 2003,或XP (其实Vista下我试过也可? .其他软g要求Q?br> - WinZIP或类似的解压~工?br> - ActiveState Perl v5.6.1或更新版本(推荐Q不是必需Q?/p>
获取和安装ACE+TAO 如果上述的workspace文g不存在,那么你需要用MakeProjectCreator (MPC)来生成它?br> 命o行如下(需要PerlQ上面已列出Q: 问题Q由于log4cpp-0.3.5rc3仅提供了vc6的工E文Ӟ因此Q用vs2005打开后,需要进行{换。但是{换后Q不能正编译,提示Custom Build Step时出C错误?/p>
分析Q因为log4cpp在生成NTEventLogAppender.dllӞ需要连接NTEventLogCategories.mc文g。所以,目讄了自定义的生成步骤去生成NTEventLogAppender.dll。但从vc6的工E文件{换时Q这些步骤却没有正确的{换过来。从而出Cq问题?/p>
解决ҎQ重新填写Custom Build StepV?/p>
其中QCommandLine填写以下内容Q?/p>
if not exist $(OutDir) md $(OutDir) Outputs填写Q?(OutDir)\NTEventLogAppender.dll 适用范围Qlog4cpp目、log4cppDLL目的Debug和Release配置。同Ӟ该方法适用于vs2003(vc7.1)?/p>
ACE/TAO的实现语a是C和C++。用ACE/TAO构徏服务器和客户端的q程出了本指南的范_但有几个概念q是值得重提Q?br />1. 接口(Interface)定义在OMG 标准?idl文g中。用TAO_IDL实用E序,TAO可以自动通过.idl文g生成C++的静态存?stubs)和框?skeletions),二者分别用于服务器端和客户?
q个问题在一般的操作pȝ里面不是一个严重的问题Q最多A被多d了一D|间。但是,在实时系l里面,如果一个Q务在规定的时间里面没有被调度q行Q系l就相当于失败了Q可能引发系l崩溃?
解决q个问题有两U手D:
1QPriority inheritance(优先U?Q如果一个高优先U的task被阻塞,与它׃n临界区的低优先的task在进入界区后,优先U就会扉K优先Utask的优先Q保证它不会被其他优先ơ高的Q务打断。从临界区退出后QC的优先恢复正常?
2QA priority ceilingQ最高优先Q,l界区分配最高优先Q如果一个taskq入临界区,把临界区的优先U赋l它Q已保证它不会被打断。从临界区退出后Qtask的优先恢复正常?/p>
http://en.wikipedia.org/wiki/Priority_inversionPriority inversion
From Wikipedia, the free encyclopedia
Contents
[hide] [edit] Solutions
[edit] See also
[edit] Notes
[edit] References
[edit] External links
A:本FAQ提供 在Windows下用VisualC++安装和构建ACE+TAO的基本说明?br> ACE+TAO也适用于其它主要的操作pȝQ例如:Linux, Solaris,
HP-UX, AIX和Tru64,q适用于一些实Ӟ嵌入式操作系l,?br> VxWorks,LynxOS, timeSys Linux和Windows CE。在Windows中,
ACE+TAO也可以用Borland C++~译器构建?/p>
.g要求Q?br> - CPUQ?Intel X86 P3 500 MHz或更?br> - 内存Q?12MB (更多内存可以提高~译速度)
- 盘I间Q?256MB交互I间+ 250MBxGBI闲I间Q取瘊于您要?br> 多少需要构?
.C++~译器要求:
- Microsoft Visual C++ 6.0 SP5 (新版本的ACE+TAO已不支持VC6?
- Microsoft Visual C++ 7.1 (VS2003)
- Microsoft Visual C++ 8.0 (VS2005)
- Microsoft Visaul C++ 9.0 (VS2008)
1. 从下载OCI TAO 1.5a的最新补?br> http://download.ociweb.com/TAO-1.5a/ACE+TAO-1.5a_with_latest_patches.zip
或从ACE+TAO的官方网站上下蝲最新Beta?br> http://download.dre.vanderbilt.edu/
2. 把上q压~文仉入至没有I格的目录中Q例如:C:\ACE_wrappers)
3. 讄环境变量 ACE_ROOT,TAO_ROOT和PATH.
例如Q如果ACE+TAO安装至C:\ACE_wrappers,则上q环境变量如下:
* ACE_ROOT=C:\ACE_wrappers
* TAO_ROOT=%ACE_ROOT%\TAO
* PATH路径需要包? %ACE_ROOT%\bin;%ACE_ROOT%\lib
4. ?%ACE_ROOT%\ace 目录中config.h文gQ文件内ҎQ?br> #define ACE_DISABLE_WIN32_ERROR_WINDOWS
#define ACE_HAS_STANDARD_CPP_LIBRARY 1
#define ACE_DISABLE_WIN32_INCREASE_PRIORITY
#include "ACE/config-win32.h"
5. %TAO_ROOT%\TAOACE.sln
在ACETAO工作?workspace)中的目构徏ACE和TAO库,TAO_IDL~译器、gperf,
ORB服务库和可执行文件以及一些公q实用工具(utilities)。他们不包含
CZ、测试和性能试。库文g安装至%ACE_ROOT%\libQ一些可执行文g安?br> ?ACE_ROOT%\bin中,其他QORB服务的可执行文gQ将安装在他们自q源代码所?br> 目录中?br>
如果您不惛_部徏议TAOACE workspace的库和可执行文gQ我们徏议构建Naming_Service
目。在开发自q应用E序里常会用到它?/p>
cd %TAO_ROOT%
%ACE_ROOT%\bin\mwc.pl -type vc71 TAOACE.mwc -- 成生visual stuido 2003 workspace文g
%ACE_ROOT%\bin\mwc.pl -type vc8 TAOACE.mwc -- 成生visual stuido 2005 workspace文g
%ACE_ROOT%\bin\mwc.pl -type vc9 TAOACE.mwc -- 成生visual stuido 2008 workspace文g
使用vs2005(vc8)~译log4cpp-0.3.5rc3
"mc.exe" -h $(OutDir) -r $(OutDir) $(SolutionDir)NTEventLogCategories.mc
"RC.exe" -r -fo $(OutDir)\$(InputName).res $(ProjectDir)\$(InputName).rc
"link.exe" /MACHINE:IX86 -dll -noentry -out:$(OutDir)\NTEventLogAppender.dll $(OutDir)\$(InputName).res
2.对象h的多路分发;
3.分及错误处理;
4.参数~码和解码;?br />5.操作的多路分?/p>
2.E序员实现在生成的I.cpp静态存根中的接口,再用惯用的CORBA技术来~写客户端和服务端的代码来进行实现?br />3. ACE/TAO提供了一个make实用E序Q这个实用程序可以跨q_的管理项目的创徏和编译。程序员~写?mpc文gQ定义了所创徏的项目所需的源代码QPerl语言脚本创徏makefile文g或Visual Sutdio的解x案。在Linux上,可以生成GC++目Q命令是 mwc.pl -type gcace。在Windows上,产生Visual studio.net 2003解决Ҏ的命令是:mwc.pl -type VC71
ACE_Acceptor框架使对新连接的侦听变得ҎQ也使创建和ȀzLq接的ACE_Svc_Handler的派生类变得Ҏ。之前我们已l了解了ACE_Svc_Handle::open()挂勾函数和服务处理器
初始化时它所扮演的角艌Ӏ本文我们回退几步Q来了解服务处理器是如何实例化的以及我们如何自定义它的行为?/p>
再看看ACE_Acceptorc,它是一个模板类Q第一个模板参数ACE_Accetpor是代表与服务建立q接的处理器。当新的q接建立ӞACE_Acceptor调用make_svc_handler()挂勾函数?/p>
实际创徏的新建服务处理器对象。ACE_Acceptor::make_svc_handler()的实现如?
默认的实现包括了两步基本操作Q?br />1. 获得一个新的SVC_HANLDER对象Q?q里是用的newq算W分配的?br />2. 讄新的服务处理器的reactor指针为ACE_Accetpor使用的reactor的?/p>
然而,如果应用E序需要通过其它方式获得SVC_HANDLER对象Q而不是通过默认的构造函数U动态分配,q又该怎么办呢QD例来_我们可能需要:
. 从一个预分配的池中获得SVC_HANDLER对象Q?br /> . 为新创徏的SVC_HANDLER传入一些额外的信息
. 使用单体的SVC_HANDLER
上面q些情ŞQ我们都可以自定义make_svc_handler()挂勾函数来实现必要的行ؓ。例?假定我们新的处理器需要拥有一个处理所有对所有接收到的消息进行集中处理的中心处理
器。这个中心处理器我们用类Processor表示。我们需要每个服务处理器都拥有一个指向中心处理器的指针,而不是Processor成ؓ一个全局讉K的指?使用全局变量的种U弊?/p>
本文不作详述)。我们的解决办法? 从ACE_Accetorz一个新c,q个新类拥有Processor的指针作成员Qƈ且,在创建新和服务处理器(Service)的时候,把这?Processor?/p>
指针作参Cq去?/p>
新的acceptorcd以这样定义:
pP现在Q当My_Acceptor接受新连接的时候,make_svc_handler()挂勾函数分配一个新的处理器(Service)Qƈ把Processor*作ؓ参数传进厅R需要注意的事,管q里使用
的是q一个构造函数Service(Processor*)。我们仍需求ؓServicecd义默认的构造函敎ͼ以满x板类ACE_Acceptor的需要?/p>
Stone Jiang
上一我们看了ACE_Svc_Handler::open()挂勾函数提供默认行ؓ的一些技巧。因为在大多数情况下Q它完成了服务创建时所需的所有事情:入事件注册新处理器和q回?/p>
在ACE_Svc_Handler中关闭操作的默认行ؓ要比在open()中初始化的代码更为复杂。这是因为关闭时的挂勑և数包含了反应?reactive)关闭和主动式(active-object)关闭两种?/p>
况,它们有相同的效果:删除所有在反应器注册的事g和确保删除ACE_Svc_handler的派生类的对象?/p>
反应式关?handle_close()): 当以下Ş况发生时被调用:
1) 事g回调函数(译注Qhandle_xxxx())q回-1Ӟ?br /> 2) 调用ACE_Reactor::remove_handler()Q传入的标记不含 DONT_CALL?br /> 反应器框架将调用handle_close()挂勾函数?ACE_Svc_handler::handle_close()的默认行为是调用ACE_Svc_Handler::destroy()销毁事件处理器?/p>
d对象式关?close()): 当ACE_Svc_Handler z的对象通过activate()函数转变Z动对象,处理器的的svc()Ҏ在它产生的线E中q行后进行回调。当svc()q回ӞU程
退出,但在它要退出时Q仍在将要退出线E的上下文中QACE_Task框架调用它的close()Ҏ。ACE_Svc_Handler::close()Ҏ调用handle_close()完成服务处理器的清理工作?/p>
因此Q不ACE_Svc_Handler对象是反应式q是d式,l束时的清理工作都在相同的地方:ACE_Svc_Handler::destroy()。如果对象是动态分配且不是ACE_Stream框架中的l成?/p>
分,destroy()删除此对象Q如果对象不是动态分配的Q析构它的责L创徏时对象所在的闭范围。如果对象是ACE_Stream的模块的l成部分Q流?或控制流的代码负责管?/p>
对象的生命期。destroy()函数应遵守这L规则来避免出现资源泄漏?/p>
无论ACE_Svc_Handler对象是反应式销毁还是主动式销毁,都会引v相同的事情发生:~ACE_Svc_Handler() (处理器的析构函数)调用ACE_Svc_Handler::shutdown()函数完成服务?/p>
理器的清理工作。shutdown()执行的这些清理操作是Q?/p>
如果处理器与反应器是兌的:
取消处理器关联的所有定时器?br /> 为处理器的流对象Q如socket)删除所有已注册的事件?br />如果处理器与再生?recycler)是关pȝQ从再生器中清除处理器?br />关闭对象?br />因此Q我们看到的l大多数情况服务处理器通过shutdown需要通过框架来清理工作,都是单的允许~省的挂勑և数得以被调用。如果你的应用程序需求更多的关闭/清理规则Q推
荐的地方是你的处理器的handle_close()挂勾Ҏ。仅仅是保把ACE_Svc_Handler::destroy()函数ZZ的handle_close()的最后一个动作,与框架清理行为的余下的行为合
q?/p>
Stone JiangACE_Svc_Handlerl常用于|络服务cȝ基类Q这是因为它很容易在d对象(Active Ojbect)
模式和反应器(Reactor)框架中用。APGW?.6节中讨论了怎么在接受器-q接?Acceptor-conector)
框架中如何把ACE_Svc_Handler作ؓ目标来用,q且Q在C++NPv2W?章中Q深度探讨了
Acceotor-Connector的相兌计?/pre>挂勾函数(Hook method)ACE_Svc_Handler::open()常是服务中新接时执行的初始化讄的地斏V?br />举例来说Q如果服务要在日志中记录新连接徏立的相关信息Qopen()函数是则是记录这个信息的地方?br />对于使用Reacotor 框架的服务检查网l数据到达,open()是执行reactor注册的地斏V?br />事实上,q正是reactor注册的地方,q种动作在服务徏立新q接旉常常见的QACE_Svc_Handler::
open()的缺省操作也正是if (this->reactor () && this->reactor ()->register_handler (this, ACE_Event_Handler::READ_MASK) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_LIB_TEXT ("%p\n"), ACE_LIB_TEXT ("unable to register client handler")), -1); return 0;所以,如果在与服务建立新连接ƈ为“读事g”注册时Q你甚至不需要在你的cM
实现open(void*)函数QACE已经Z做了q一?另外Q请CQ如果reactor注册p|Q?br />默认的open()函数会返?1Q它会引起Acceptor-Connector框架关闭新徏的连接和删除q个
事g处理?handler)?br />Stone Jiang
http://www.shnenglu.com/ace/Stone Jiang 2006-08-27 23:48 发表评论]]>