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


    转载于:http://www.cnblogs.com/TianFang/archive/2006/12/04/581793.html

    ACE Guard类属

    与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更加简洁,并且会自动解锁,免除了一部分后顾之忧。

    注意:

    1. Guard只能帮你自动加解锁,并不能解决死锁问题,特别是对于那些非递归的互斥体来说使用Guard尤其要注意防止死锁。

    Guard是在Guard变量析构时解锁,如果在同一函数中两次对同一互斥体变量使用Guard要注意其对象生命周期,否则容易造成死锁。

  • 相关阅读:
    Hibernate的一些操作
    工作心得
    放款流程
    关于C#事件的自我构想和学习
    委托之winForm窗口间传递数据
    C#中string[]数组和list<string>泛型的相互转换 【转】
    关于注册界面中的一些规则设计时要注意
    系统界面设计---风格
    关于系统注册,做卡号重校验
    关于系统设计中的硬件开发
  • 原文地址:https://www.cnblogs.com/shmilxu/p/4860405.html
Copyright © 2020-2023  润新知