ACE递归锁读写锁

来源:互联网 发布:java中ant使用 编辑:程序博客网 时间:2024/05/13 15:55
1.不同平台使用有差异性/** * @class ACE_Thread_Mutex * * @brief ACE_Thread_Mutex wrapper (only valid for threads in the same * process). * * This implementation is optimized for locking threads that are * in the same process.  It maps to <CRITICAL_SECTION>s on NT * and <ACE_mutex_t> with <type> set to <USYNC_THREAD> on UNIX. * ACE_Thread_Mutex is recursive on some platforms (like * Win32). However, on most platforms (like Solaris) it is not * recursive.  To be totally safe and portable, developers * should use ACE_Recursive_Thread_Mutex when they need a * recursive mutex. */ACE的ACE_Thread_Mutex互斥锁在windows平台上是可重入的,而在Linux平台上是不可重入的,原因上面也有说明Windows下是使用Critical Section实现的,而Critical Section在window下是可递归的。Linux下的pthread_mutex_t锁默认(USYNC_THREAD)是非递归的。可以显示的设置PTHREAD_MUTEX_RECURSIVE属性,将pthread_mutex_t设为递归锁。   2.锁最好不要复制在ACE中ACE_Thread_Mutex也没有拷贝构造函数,即使有使用起来也会很不安全,一般都用锁的拷贝或者引用来传递。如果锁可以拷贝,那么可能出现两个线程同时拥有一个锁,同时对数据操作的情况,这个时候和没有加锁一样了。 3.读写锁必须使用得当 读写锁允许多个线程同时持有一个锁进行读取,但只有一个线程能够持有这个锁进行写入,可以带来效率的提高。特别是在受保护的多个线程常被多个线程读取,但不常被写入,或是只被很少几个线程写入。但是在大多数情况下读写锁都比互斥体要慢,因此,只在读取竞争大大超过写入竞争的时候使用它。   4.递归锁Demo[cpp] view plaincopy// thread_recursive_mutex.cpp    #include "ace/Task.h"    typedef ACE_Recursive_Thread_Mutex MUTEX;    // will cause deadlock in linux, in win32 its ok  //typedef ACE_Thread_Mutex MUTEX;    class Logger  {  public:      void log(void)      {          ACE_GUARD(MUTEX, mon, m_metex);            //in some case          lockAgain();      }        void lockAgain()      {          // acquires the same mutex as log();          ACE_GUARD(MUTEX, mon, m_metex);      }  private:      MUTEX m_metex;  };    int ACE_TMAIN(int, ACE_TCHAR *[])  {      Logger log;      log.log();      return 0;  };    5.读写锁Demo 下面这个Demo模拟的是检测家庭中的设备是否在网络中,一般添加设备很少,而要经常检查,这种场合可以使用,在添加两个设备后,每隔1秒读取一次设备是否在网络中,开启读取线程3秒后移除一个设备,然后继续读取。[cpp] view plaincopy// thread_rw_mutex.cpp    #include "ace/Task.h"  #include <iostream>  #include <list>  #include <algorithm>  #include <functional>  using namespace std;    class Device  {  public:      Device(int id):deviceID(id){}      int deviceID;  };    class isEqual  {  public:      isEqual(int id):m_id(id){}      bool operator() (Device *device)      {          return device->deviceID == m_id;      }  private:      int m_id;        };    class HADiscoverAgent  {  public:      void addDevice(Device *device)      {          ACE_WRITE_GUARD(ACE_RW_Thread_Mutex, mon, m_rwmutex);          m_DeviceList.push_back(device);          ACE_DEBUG((LM_DEBUG, ACE_TEXT("Device is add, the device id is: %d\n"), device->deviceID));      }        void removeDevice(Device *device)      {          ACE_WRITE_GUARD(ACE_RW_Thread_Mutex, mon, m_rwmutex);          m_DeviceList.remove(device);          ACE_DEBUG((LM_DEBUG, ACE_TEXT("Device is remove, the device id is: %d\n"), device->deviceID));          ACE_OS::sleep(5);      }        // check device is in net, return the device id or return -1      int containsDevice(Device *device)      {          ACE_READ_GUARD_RETURN(ACE_RW_Thread_Mutex, mon, m_rwmutex, -1);          list<Device *>::iterator pos = find_if(m_DeviceList.begin(), m_DeviceList.end(),               isEqual(1));            int ret = -1;          if (pos != m_DeviceList.end())          {              ret = (*pos)->deviceID;          }          return ret;      }  private:      ACE_RW_Thread_Mutex m_rwmutex;      list<Device*> m_DeviceList;  };    class myThread:public ACE_Task_Base  {  public:      myThread(HADiscoverAgent *da, Device *device):m_da(da), m_device(device){}      virtual int svc()      {          // check 10 times           for (int i=0; i<10; i++)          {              int tmp = m_da->containsDevice(m_device);              if (tmp != -1)              {                  ACE_DEBUG((LM_DEBUG, ACE_TEXT("Device %d is in net!\n"), tmp));              }              else              {                  ACE_DEBUG((LM_DEBUG, ACE_TEXT("Device %d is not in net!\n"), m_device->deviceID));              }                            ACE_OS::sleep(1);          }          return 0;      }  private:      HADiscoverAgent *m_da;      Device *m_device;  };      int ACE_TMAIN(int, ACE_TCHAR *[])  {      Device d1(1);      Device d2(2);      HADiscoverAgent da;      da.addDevice(&d1);      da.addDevice(&d2);        // start thread to read device ten times in 10s      myThread mTh(&da, &d1);      mTh.activate();            // read the device info before remove device      ACE_OS::sleep(3);        // remove device, now the write is use, da can read until write is over      da.removeDevice(&d1);      mTh.wait();      return 0;    };  

0 0