3.介绍-改进服务端,通过POA策略之显示激活和用户自定义对象ID
介绍——改善服务端
在本节,我们将在之前提到的“简单服务器”之上进行改进。我们将会讨论如何使把POA策略赋给对象ID。
在先前的示例中,我们用了 Quoter_Stock_Factory_i 的两个域来表示两支股票。如果我们想创建上百支股票,那么这种方法就缺少扩展性。我们需要用某个集合来保持对股票对象的跟踪,比如为股票符号建立索引。一种解决办法是使用STL map或与之差不多的集合类,但这样明显太浪费了。毕意,ORB已经以对象ID为索引建立了对象的集合。如果仅能自己选择ID,那么我们的问题就能得已解决。一个好消息是:POA允许这样做;一个坏消息是我们必须创建子POA。那这是为什么呢?这是因为RootPOA的ID是被ORB分配了的,我们不想要与它们冲突。此外,创建一个独立的POA比管理它更容易,因为多个应用程序的组件可以获得它们自己的POA,它们能被视为私有的命字空间。
子POA的创建
如前所述,我们可以访问RootPOA:
CORBA::Object_var poa_object =
orb->resolve_initial_references ("RootPOA");
PortableServer::POA_var poa =
PortableServer::POA::_narrow (poa_object.in ());
现在我们为子POA创建策略。在这个应用场景下,我们想使用USER_ID策略,这样就可以把它赋自己的这些ID。我们还想使用 NO_IMPLICIT_ACTIVATION
策略,以便于对我们的POA有更多的控制。POA具有许多我们可以控制的策略,但我们在示例中只使用默认的策略。在$TAO_ROOT/examples/POA/目录下有许多示例演示了如何使用这些策略。
策略存储在序列中的,所以我们首先创建序列并初始化它的长度。
CORBA::PolicyList policies (2);
policies.length (2);
接下来我们创建策略:
policies[0] =
poa->create_id_assignment_policy (PortableServer::USER_ID);
policies[1] =
poa->create_implicit_activation_policy (PortableServer::NO_IMPLICIT_ACTIVATION);
再然后我们创建子POA:
PortableServer::POA_var stock_factory_poa =
poa->create_POA ("Stock_Factory_POA",
poa_manager.in (),
policies);
注意的是,我们与RootPOA共用了POA管理器,于是我们只需要用一个POA管理就可以控制这两个POA的状态。新的POA复制了策略,所以我们为了避免内存泄漏,所以需要销毁它们。
for (CORBA::ULong i = 0; i != policies.length (); ++i)
{
policies[i]->destroy ();
}
在子POA中激活对象
现在我们必须使用这个POA来激活股票对象了。为了使示例简化,我们假设我们可以从标准输入设备(stdin)中读入这些股票信息,比如这样:
while (!std::cin.eof () && std::cin.peek () != EOF)
{
const int max_symbol_length = 8;
char symbol[max_symbol_length];
const int max_full_name_length = 64;
char full_name[max_full_name_length];
double price;
std::cin.getline (symbol, max_symbol_length, '\n');
std::cin.getline (full_name, max_full_name, '\n');
std::cin >> price;
std::cin.ignore (1, '\n');
// The interesting stuff goes here!
}
为每个符号、全称和价格的三元组中, 我们创建股票实现的对象:
PortableServer::ServantBase_var servant =
new Quoter_Stock_i (symbol, full_name, price);
ServantBase_var 充当的角色很象自动指针,在发生异常的情况下,它可以小心的管理对象的回收操作。这次我们不能使用_this() 来激活对象,这是因数我们要想创建自己对象ID:
PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId (symbol);
然后我们通过id来激活对象:
stock_factory_poa->activate_object_with_id (oid.in (),
servant.in ());
请小心,不要在这些对象上调用_this(),如果这样就会在RootPOA中激活它们,被激活了两次!虽然在不同的POA中(甚于有时还在同一个POA中)多次激活一个对象是完全合法的,它是在现在的应用情景中我们并不需要这样做。
修改Stock Factory
现在我们必须实现Stock Factory的不同版本。我们传一个子POA的引用到构造函数中并维护这个引用:
class Quoter_Stock_Factory_i : public POA_Quoter::Stock_Factory
{
public:
Quoter_Stock_Factory (PortableServer::POA_ptr stock_factory_poa)
: stock_factory_poa_ (PortableServer::POA::_duplicate (stock_factory_poa))
{}
Quoter::Stock_ptr get_stock (const char *symbol)
throw (Quoter::Invalid_Stock_Symbol);
private:
PortableServer::POA_var stock_factory_poa_;
};
注意,我们复制了POA,这样才遵从惯用的CORBA对输入参数的内存管理规则。尽管构造函数并不是CORBA操作,这样做我们可以把这个规则使用得更广泛,如果我们坚持使用CORBA这套规则时可以减少误解。
get_stock 操作的实现更为有趣。首先我们依据符号创建对象的ID:
Quoter::Stock_ptr
Quoter_Stock_Factory_i::get_stock (const char *symbol)
throw (Quoter::Invalid_Stock_Symbol)
{
PortableServer::ObjectId_var oid =
PortableServer::string_to_ObjectId (symbol);
接下来在POA中查找对象的ID:
try {
CORBA::Object_var tmp =
this->stock_factory_poa_->id_to_reference (oid.in ());
最后将对象的引用narrow到正常的类型并返回它:
return Quoter::Stock::_narrow (tmp.in ());
}
要是符号无效,POA就找不对正确的对象ID,只好抛出异常:
catch (PortableServer::POA::ObjectNotActive &) {
throw Quoter::Invalid_Stock_Symbol ();
}
}
股票对象的内存管理
迄今为止,我们还尚为讨论伺服代码(servants)的内存管理问题。现在是讨论它的最好时机了,因为股票对象已完全授控于POA了。POA为伺服代码提供了引用计数。你并不需要使用引用计数,如果你遵从了这一点,那绝大多数的内存管理就相当的简单了。那为什么不是所有的时候都可以不使用引用计数呢?那是因为有的应用程序不需要它。举例来说,我们先前的简单服务不需要任何复杂的对象管理,于是所有的对象都是在栈(stack)上创建的。
如果想在POA中使用引用计数,你必须重载_add_ref() 和remove_ref() 这两个方法用来增加或减少引用的数目。 一旦数目回到0,你就可以安全的删除对象(但要记住,计数数目是从1开始的!)。
把这些方法实现为线程安全是一件繁琐的工作。为了减化这个工作,我们混合使用了PortableServer::RefCountServantBase 这个作为基类,像这样:
class Quoter_Stock_i
: public virtual POA_Quoter::Stock,
public virtual PortableServer::RefCountServantBase
{
public:
Quoter_Stock_i (const char *symbol,
const char *full_name,
CORBA::Double price);
// as before
};
TAO中PortableServer::RefCountServantBase 的实现也是线程安全的,于是你可以用这个技术在你的多线程服务中动态的销毁对象。您简单的委托POA来控制,一旦所有线程调用了对象中止,当休眠该对象时,POA将会调用 _remove_ref(),这样如果这个对象还在使用中就不会被删除。也请记住如果你要使用对象请增加它的引用记数。
练习
从简单服务的文件作如下修改:
-
Stock_i.h: 使用引用计数控制伺服代码的内存管理。
-
Stock_Factory_i.h: Apply the changes described above to use a child POA with the appropriate policies.
-
Stock_Factory_i.cpp: Apply the changes described above to use a child POA with the appropriate policies.
-
server.cpp: Create the child POA, initialize the stock objects from the stdin, and create the right stock factory class.
你能够使用相同的Quoter.idl, Stock_i.cpp 和MPC 文件.
解决方案
在你的解决方案在同下面的文件作比较:
Does this solution scale when the number of stock symbols is in the thousands or millions? Find out about Servant Locators and Servant Activators in the POA!
Testing
有一个简单的输入文件可用. 你可以使用简单客户端来检查结果:
$ server < stock_list.txt > ior_file
$ client file://ior_file AAAA BBBB MSFT RHAT CCCC
也测试一下无效的符号!
More Reading
The Henning and Vinoski CORBA book discusses POA policies in detail. Likewise, the Schmidt and Vinoski columns in C++ Report also include several articles about the POA. Finally, the TAO distribution includes examples that illustrate how to use the POA policies.
分享到:
相关推荐
- **策略**:介绍了CORBA策略的概念及其在POA中的应用,如生命周期策略、ID分配策略等。 - **POA策略**:深入探讨了各种与POA相关的策略设置方法。 - **POA的创建**:讨论了创建POA的方法及步骤。 - **POA与POA管理...
根据提供的标题、描述以及部分文本内容,我们可以详细探讨与“POA-TCN-BiGRU-Attention”鹈鹕算法相关的几个核心知识点。这一算法主要应用于优化时间卷积双向门控循环单元(TCN-BiGRU)并结合注意力机制进行多变量...
- **用户自定义异常**:通过 IDL 定义并在服务端抛出,客户端捕获处理。 #### 八、IDL到Java的编译器 - **编译结果**: - 为客户端生成存根类。 - 为服务端生成 POA 类。 - **IDL特性映射**: - 接口属性。 - ...
这个"TD_TP-POA-master"文件夹中的内容可能包含了关于如何设置POA、创建对象引用、处理请求以及如何利用POA进行并发控制等方面的示例代码和讲解。通过深入学习和实践这些材料,开发者可以更好地理解和掌握Java中的...
POA-DPSA算法用于水库优化计算,采用C++语言
哈里斯鹰优化算法HHO-鹈鹕优化算法POA-北方苍鹰优化算法NGO-秃鹰优化算法BES-阿基米德优化算法AOA【单目标优化算法】在23个测试函数上对比(Matlab代码实现) 哈里斯鹰优化算法HHO-鹈鹕优化算法POA-北方苍鹰优化...
- 改进2:融合改进的正余弦策略 - 改进3:Levy飞行策略跳出局部最优 - 将改进后的IPOA与多种算法进行对比 - 注释详细 以下是一些学习matlab的经验:1. 开始学习MATLAB之前,建议你阅读官方提供的MATLAB文档和教程,...
基于鹈鹕算法(POA)优化卷积神经网络-长短期记忆网络(CNN-LSTM)回归预测,POA-CNN-LSTM多输入单输出模型。 优化参数为:学习率,隐含层节点,正则化参数。 评价指标包括:R2、MAE、MSE、RMSE和MAPE等,代码质量极高...
- **同进程客户端和服务端**:演示了在同一进程中运行客户端和服务端的情形,着重于 ORB 初始化、对象引用获取及激活 POA 的过程。 - **ORB 初始化**:描述了初始化 ORB 对象的基本步骤。 - **获取 RootPOA**:...
chain-poa-php:ForwardBlock PoA网络模型PHP
节约 ECO-nomize 项目 (Hack in PoA) 生产项目: :
标题中的“poa1_poa_POA算法_逐步优化用于水库优化调度_”明确指出了我们要探讨的主题,即POA(Progressive Optimization Algorithm)算法在水库优化调度中的应用。POA算法是一种逐步优化的方法,其核心思想是通过...
标题中的"POA.rar_35poa_35poa.con_poa"可能是指一个与"Programa de Obras Anuales"(年度工程项目计划)相关的压缩文件,其中"POA"是西班牙语中的缩写,对应英文的"Annual Works Program"。这个文件可能包含了关于...
通过上述步骤,POA算法能够在考虑不确定性和复杂性的前提下,为水库调度提供更科学、合理的决策支持。这种方法不仅可以提高水资源利用效率,还能在面对气候变化等不确定性因素时保持良好的适应性。在实际应用中,POA...
水库调度POA算法,动态规划的改进方法。
鹈鹕优化算法 (Pelican Optimization Algorithm, POA) 是一种基于群体智能的元启发式优化算法,它模拟了鹈鹕的捕食行为和社会交互特性,用于解决复杂的优化问题。 POA的工作机制主要包括: 捕食行为:模拟鹈鹕群...
在激活POA管理器之前,对象可能无法响应请求。 #### 四、安装指南 文档还详细介绍了如何安装ORBit: - **从RPM包安装** - 对于使用RPM包管理系统的Linux发行版,可以直接安装预编译好的ORBit RPM包。 - **从源代码...
1. **ORB(Object Request Broker)**:对象请求代理,是CORBA的核心组件,负责对象定位、消息传递和对象间的交互。 2. **IOR(Interface Object Reference)**:接口对象引用,是ORB为每个对象生成的唯一标识,...
在POA流程中,通常涉及到对交易的授权、审批等关键环节,因此,dpac-pci-poa-web的设计与实现需要高度关注用户体验和数据安全性。作为一款基于JavaScript开发的应用,它利用了这一动态编程语言的灵活性和强大的功能...
- **自定义ORB**:通过接收器和对象封装器等方式定制ORB的行为。 - **事件队列**:用于管理对象接收到的消息。 - **命名服务中的后备存储器**:提供持久化存储,即使服务重启也能保持对象信息。 - **Web命名**:...