ACE同步策略实现(-) :: 风之谷

来源: BlogBus 原始链接: http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=180955 存档链接: https://web.archive.org/web/20041027034018id_/http://www.blogbus.com:80/blogbus/blog/diary.php?diaryid=180955


风之谷 程序员的技术天空 <<<开张一个月 | 首页 | JAWS2 分析报告 IV>>> ACE同步策略实现(-) 时间:2004-05-18 在我们进行多线程编程时,经常考虑的一个问题,就是如何使你的代码线程安全。 为了实现线程安全,我们常常要实现多种版本的库 多线程,单线程。 这给我们的代码开发以及维护带来很多的问题。 为了能够简化同步操作方面的编程难度,在ACE中大量使用了Traits 什么是trait?传达由别的累或者算法在编译时用于确定策略的信息。 traits 是一种用于收集一组trait的途径。 traits和traits为C++提供了基于策略的类设计。 traits与Strategy模式的区别 traits 涉及的时一组类成员或方法的替换,它们可以在编译的时候通过C++参数化类型来静态绑定。 Strategy 提供的类行为改变是通过÷实现特点接口的虚方法来动态绑定的。 traits是一种类型驱动,依照具体的类型产生相应的模板类或者模板函数,通过模板参数实现 根据环境需要改变其行为方式,通过静态绑定来进一步提高效率。 在C++NPV1 P224中 给出了在Message_Queue类实现,包含的内容 - Monitor Object 监控对象设计模式 - Thread-Safe Interface 提供了线程安全的接口模式 - Scoped Locking ACE_GUARD*实现了对同步锁封装机制 在C++NPV1 P225-p228 给出了有关Message_Queue的简化实现 对于C++中的模板大家都应该有所了解,Traits就是依赖与模板的显式特例化, 来实现特定类型信息的特例化。有关ACE_Guard的实现,通过ACE_Guard来实现局域锁的概念。 通过在类声明是指定锁类型就可以很方便实现进程,线程安全的消息队列 ACE_Message_Queue<ACE_MT_SYNCH> message_queue_;如果程序是单线程的话, 可以ACE_Message_Queue<ACE_NULL_SYNCH> message_queue_。 现在从ACE中的ACE_Task以及ACE_Message_Queue的源代码,会发现一些意思的参数 template <ACE_SYNCH_DECL> class ACE_Task : public ACE_Task_Base { ...... ACE_Message_Queue<ACE_SYNCH_USE> *msg_queue_; } #define ACE_SYNCH_DECL class ACE_SYNCH_MUTEX_T, class ACE_SYNCH_CONDITION_T #define ACE_SYNCH_USE ACE_SYNCH_MUTEX_T, ACE_SYNCH_CONDITION_T 再分析一下ACE_Message_Queue的实现 template <ACE_SYNCH_DECL> class ACE_Message_Queue : public ACE_Message_Queue_Base { //与锁相关的类定义,分别是 ACE_SYCH_DECL中定义的 互斥体和条件变量的内容 ...... // = Synchronization primitives for controlling concurrent access. /// Protect queue from concurrent access. ACE_SYNCH_MUTEX_T lock; /// Used to make threads sleep until the queue is no longer empty. ACE_SYNCH_CONDITION_T not_empty_cond; /// Used to make threads sleep until the queue is no longer full. ACE_SYNCH_CONDITION_T not_full_cond; } ACE_MT_SYNCH 中的描述信息 #define ACE_MT_SYNCH ACE_Thread_Mutex, ACE_Condition_Thread_Mutex class ACE_Export ACE_MT_SYNCH { public: typedef ACE_Thread_Mutex MUTEX; typedef ACE_Null_Mutex NULL_MUTEX; typedef ACE_Process_Mutex PROCESS_MUTEX; typedef ACE_Recursive_Thread_Mutex RECURSIVE_MUTEX; typedef ACE_RW_Thread_Mutex RW_MUTEX; typedef ACE_Condition_Thread_Mutex CONDITION; typedef ACE_Condition_Recursive_Thread_Mutex RECURSIVE_CONDITION; typedef ACE_Thread_Semaphore SEMAPHORE; typedef ACE_Null_Semaphore NULL_SEMAPHORE; }; 这些是和多线程相关的一组traits class ACE_Export ACE_NULL_SYNCH { public: typedef ACE_Null_Mutex MUTEX; typedef ACE_Null_Mutex NULL_MUTEX; typedef ACE_Null_Mutex PROCESS_MUTEX; typedef ACE_Null_Mutex RECURSIVE_MUTEX; typedef ACE_Null_Mutex RW_MUTEX; typedef ACE_Null_Condition CONDITION; typedef ACE_Null_Condition RECURSIVE_CONDITION; typedef ACE_Null_Semaphore SEMAPHORE; typedef ACE_Null_Mutex NULL_SEMAPHORE; }; 为何使用这些线程模式 研究ACE_Message_Queue的实现可以得知,在进入需要保护相关的临界资源前,都有这么一句话, ACE_GUARD_RETURN (ACE_SYNCH_MUTEX_T, ace_mon, this->lock, -1); 分析一下这个宏,目的是减轻系统的功能,增加 ACE_SYNCH_MUTEX_T 是前面提到的同步机制的Traits类集合 ace_mon ACE_Guard< ACE_SYNCH_MUTEX_T > ace_mon (this->lock_) (由宏定义来进行实现 OBJ ACE_Guard< MUTEX > OBJ (LOCK);) this->lock_ ACE_SYNCH_MUTEX_T lock_ (#define ACE_SYNCH_MUTEX_T _ACE_SYNCH_MUTEX_T ,使用了宏定义中的锁类) ACE_GUARD_RETURN #define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN) ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return RETURN) 以下是一组尝试死锁,并提供死锁恢复处理的宏,定义ACTION以及REACTION的操作 // Convenient macro for testing for deadlock, as well as for detecting // when mutexes fail. // 定义了完整的锁操作模型 #define ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ACTION, REACTION)
ACE_Guard< MUTEX > OBJ (LOCK);
if (OBJ.locked () != 0) { ACTION; }
else { REACTION; } // 简化参数后的宏定义 #define ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, REACTION)
ACE_GUARD_ACTION(MUTEX, OBJ, LOCK, ;, REACTION) #define ACE_GUARD(MUTEX, OBJ, LOCK)
ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return) #define ACE_GUARD_RETURN(MUTEX, OBJ, LOCK, RETURN)
ACE_GUARD_REACTION(MUTEX, OBJ, LOCK, return RETURN)

define ACE_WRITE_GUARD(MUTEX,OBJ,LOCK) \

ACE_Write_Guard< MUTEX > OBJ (LOCK);
if (OBJ.locked () == 0) return;

define ACE_WRITE_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \

ACE_Write_Guard< MUTEX > OBJ (LOCK);
if (OBJ.locked () == 0) return RETURN;

define ACE_READ_GUARD(MUTEX,OBJ,LOCK) \

ACE_Read_Guard< MUTEX > OBJ (LOCK);
if (OBJ.locked () == 0) return;

define ACE_READ_GUARD_RETURN(MUTEX,OBJ,LOCK,RETURN) \

ACE_Read_Guard< MUTEX > OBJ (LOCK);
if (OBJ.locked () == 0) return RETURN; 在ACE_Message_Queue的代码中,还有很多有意思的东东,例如有关条件变量的实现问题。 这部分的内容将在下一篇文章继续讨论。 jnn 发表于 2004-05-18 14:58 引用Trackback(0) | 编辑 评论 [traits与Strategy模式的区别] 依我之见,traits是strategy的一种实现,两者居于不同的层次。根据情况,strategy可以用traits,也可以用策略类来实现。 Merlin Ran ( merlinran.blogone.net ) 发表于 2004-05-19 08:53 traits 策略的替换是在编译时确定的。 strategy是通过动态绑定实现的。 一个是静态替换,一个是动态绑定,差别还是很大的。 traits应该是templete模式的一种实现。 jnn ( jnn.blogbus.com ) 发表于 2004-05-20 17:08 发表评论 最后更新 ACE Tutorial 01-page04 ACE Tutorial 01-page03 ACE Tutorial 01-page02 ACE Tutorial 01-page01 ACE 教程 (前言) 与ORB相关的API JAWS2 分析报告 IV JAWS2 分析报告 III JAWS2分析报告 II JAWS2 分析报告 I