六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 37|回复: 0

ACE线程管理机制-并发控制(2)

[复制链接]

升级  68.2%

265

主题

265

主题

265

主题

进士

Rank: 4

积分
841
 楼主| 发表于 2013-1-28 19:23:21 | 显示全部楼层 |阅读模式
ACE线程管理机制-并发控制(2)


与C一级的互斥体API相比较,Mutex包装为同步多线程控制提供了一种优雅的接口。但是,Mutex潜在地容易出错,因为程序员有可能忘记调用release方法(当然,C级的互斥体API更容易出错)。这可能由于程序员的疏忽或是C++异常的发生而发生,然而,其导致及其严重的后果--死锁。


因此,为改善应用的健壮性,ACE同步机制有效地利用C++类构造器和析构器的语义来确保Mutex锁被自动获取和释放。


ACE提供了一个称为Guard、Write_Guard和Read_Guard的类族,确保在进入和退出C++代码块时分别自动获取和释放锁。


Guard类是最基本的守卫机制,定义可以简化如下(实际定义比这相对要复杂而完善一点):
template <class LOCK>class Guard{public:    Guard (LOCK &l): lock_ (&l){ lock_.acquire (); }    ˜Guard (void) {    lock_.release (); }private:    LOCK lock_;}
Guard类的对象定义一"块"代码,在其上锁被自动获取,并在退出块时自动释放,即使是程序抛异常也能保证自动解锁。这种机制也能为Mutex、RW_Mutex和Semaphore同步封装工作。


对于读写锁,由于加锁接口不一样,ace也提供了相应的Read_Guard和Write_Guard类,Read_Guard和Write_Guard类有着与Guard类相同的接口。但是,它们的acquire方法分别对锁进行读和写。


缺省地, Guard类构造器将会阻塞程序,直到锁被获取。会有这样的情况,程序必须使用非阻塞的acquire调用(例如,防止死锁)。因此,可以传给ACE Guard的构造器第二个参数(请参看原始代码,而不是我这里的简化代码),指示它使用锁的try_acquire方法,而不是acquire。随后调用者可以使用Guard的locked方法来原子地测试实际上锁是否已被获取。


用Guard重写上一节的Thread1方法如下(注释了的部分是原有代码):
void* Thread1(void *arg) {    ACE_Guard<ACE_Thread_Mutex> guard(mutex);    //mutex.acquire();    ACE_OS::sleep(3);    cout<<endl<<"hello thread1"<<endl;    //mutex.release();    return NULL; } 
相比较而言,使用Guard更加简洁,并且会自动解锁,免除了一部分后顾之忧。


注意:


Guard只能帮你自动加解锁,并不能解决死锁问题,特别是对于那些非递归的互斥体来说使用Guard尤其要注意防止死锁。
Guard是在Guard变量析构时解锁,如果在同一函数中两次对同一互斥体变量使用Guard要注意其对象生命周期,否则容易造成死锁。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表