受到保护的操作称作受保护操作。受保护操作被认为非常关键,需要强制互斥。受保护对象是至少拥有一个受保护操作的对象。
实施受保护对象的一种方法是给它一个互斥锁,这样显式设置为受保护的每个操作会在操作开始时锁定互斥锁,并在结束时释放它。
RiCMonitor 成员会添加到受保护对象的结构中。例如:
typedef struct A A;
struct A {
RiCMonitor ric_monitor;
/* other members of A */
};
RiCMonitor 是 IBM® Rational® Rhapsody® 框架中定义的一种监视器类型。
ric_monitor 子对象仅用于标记为受保护的该对象的操作。您可以使用 CG::Operation::Concurrency 属性来将操作标记为受保护。
受保护操作在包装程序操作中受保护,而该操作负责用于保护。受保护操作会生产为专用操作,如下所示:
例如,会为对象 B 的受保护操作 increase() 生成两个函数:
包装程序操作的声明生成在对象的规范文件中:
int B_increase(B* const me, int i);
包装程序操作 increase() 会获取 ric_monitor 对象上的锁、调用受保护操作并最终释放锁定:
int B_increase(B* const me, int i) {
int wrapper_return_value;
RIC_OPERATION_LOCK(&me->ric_monitor);
wrapper_return_value = B_increase_guarded(me, i);
RIC_OPERATION_FREE(&me->ric_monitor);
return wrapper_return_value;
}
一旦包装程序功能获取了锁,受保护操作就受到保护并且可以执行其关键操作,其他对象无法在锁定释放前访问其关键操作:
static int B_increase_guarded(B* const me, int i) {
{
/*#[ operation increase(int) */
return i++;
/*#]*/
}
}
类似,受保护对象的 cleanup 操作会生成在执行清除的包装程序操作和受保护操作中。例如,受保护对象 B 的清除首先锁定 B,然后调用 cleanup_guarded() 来执行实际的清除:
void B_Cleanup(B* const me) {
RIC_OPERATION_LOCK(&me->ric_monitor);
B_Cleanup_guarded(me);
}
void B_Cleanup_guarded(B* const me) {
RiCMonitor_cleanup(&me->ric_monitor);
}
您还可以直接使用 lock 和 free 宏,以避免需要对包装程序操作的额外支持。