zoukankan      html  css  js  c++  java
  • ACE线程管理机制并发控制(2)

    ACE Guard类属

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

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

    ACE提供了一个称为GuardWrite_GuardRead_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要注意其对象生命周期,否则容易造成死锁。

  • 相关阅读:
    (Java随机数举例)随机扔一千次硬币的正反次数
    hibernate+spring的整合思路加实例(配图解)
    从零开始学C++之IO流类库(三):文件的读写、二进制文件的读写、文件随机读写
    ssh连接Linux自动断开后再也无法连上的问题
    面试题10:二进制中1的个数
    C 语言统计关键字出现次数
    在Eclipse中Attach Source
    Visual Sudio 2012转换界面风格
    java 判断字符串IP合法性以及获取IP的数值形式
    java.lang.string split 以点分割字符串无法正常拆分字符串
  • 原文地址:https://www.cnblogs.com/TianFang/p/581793.html
Copyright © 2011-2022 走看看