Linux平台用C++封装线程读写锁

Linux平台用C++封装线程读写锁

    在Linux平台上已经有现成的线程读写锁pthread_rwlock_t以及相关API,现将这些API封装成与Win32平台上相同的接口,以便于编写跨平台程序。这些API包括pthread_rwlock_init,pthread_rwlock_rdlock,pthread_rwlock_tryrdlock,pthread_rwlock_wrlock,pthread_rwlock_trywrlock,pthread_rwlock_unlock,pthread_rwlock_destroy,可在Linux在线手册上查阅它们的说明。下边的代码在VS2005中编辑,在Fedora 13虚拟机中编译,测试通过。

RWLockImpl.h

[cpp] view plain copy
  1. #ifndef _RWLockImpl_Header  
  2. #define _RWLockImpl_Header  
  3.   
  4. #include <iostream>  
  5. #include <pthread.h>  
  6. #include <errno.h>  
  7. #include <assert.h>  
  8.   
  9. using namespace std;  
  10.   
  11. /* 
  12.  读写锁允许当前的多个读用户访问保护资源,但只允许一个写读者访问保护资源 
  13. */  
  14.   
  15. //-----------------------------------------------------------------  
  16. class CRWLockImpl  
  17. {  
  18. protected:  
  19.     CRWLockImpl();  
  20.     ~CRWLockImpl();  
  21.     void ReadLockImpl();  
  22.     bool TryReadLockImpl();  
  23.     void WriteLockImpl();  
  24.     bool TryWriteLockImpl();  
  25.     void UnlockImpl();  
  26.   
  27. private:  
  28.     pthread_rwlock_t m_rwl;  
  29. };  
  30.   
  31. //-----------------------------------------------------------------  
  32.   
  33. class CMyRWLock: private CRWLockImpl  
  34. {  
  35. public:  
  36.   
  37.     //创建读/写锁  
  38.     CMyRWLock(){};  
  39.   
  40.     //销毁读/写锁  
  41.     ~CMyRWLock(){};  
  42.   
  43.     //获取读锁  
  44.     //如果其它一个线程占有写锁,则当前线程必须等待写锁被释放,才能对保护资源进行访问  
  45.     void ReadLock();  
  46.   
  47.     //尝试获取一个读锁  
  48.     //如果获取成功,则立即返回true,否则当另一个线程占有写锁,则返回false  
  49.     bool TryReadLock();  
  50.   
  51.     //获取写锁  
  52.     //如果一个或更多线程占有读锁,则必须等待所有锁被释放  
  53.     //如果相同的一个线程已经占有一个读锁或写锁,则返回结果不确定  
  54.     void WriteLock();  
  55.   
  56.     //尝试获取一个写锁  
  57.     //如果获取成功,则立即返回true,否则当一个或更多其它线程占有读锁,返回false  
  58.     //如果相同的一个线程已经占有一个读锁或写锁,则返回结果不确定  
  59.     bool TryWriteLock();  
  60.   
  61.     //释放一个读锁或写锁  
  62.     void Unlock();  
  63.   
  64. private:  
  65.     CMyRWLock(const CMyRWLock&);  
  66.     CMyRWLock& operator = (const CMyRWLock&);  
  67. };  
  68.   
  69. inline void CMyRWLock::ReadLock()  
  70. {  
  71.     ReadLockImpl();  
  72. }  
  73.   
  74. inline bool CMyRWLock::TryReadLock()  
  75. {  
  76.     return TryReadLockImpl();  
  77. }  
  78.   
  79. inline void CMyRWLock::WriteLock()  
  80. {  
  81.     WriteLockImpl();  
  82. }  
  83.   
  84. inline bool CMyRWLock::TryWriteLock()  
  85. {  
  86.     return TryWriteLockImpl();  
  87. }  
  88.   
  89. inline void CMyRWLock::Unlock()  
  90. {  
  91.     UnlockImpl();  
  92. }  
  93.   
  94. #endif  
RWLockImpl.cpp
[cpp] view plain copy
  1. #include "RWLockImpl.h"  
  2.   
  3. CRWLockImpl::CRWLockImpl()  
  4. {  
  5.     if (pthread_rwlock_init(&m_rwl, NULL))  
  6.         cout<<"cannot create reader/writer lock"<<endl;  
  7. }  
  8.   
  9. CRWLockImpl::~CRWLockImpl()  
  10. {  
  11.     pthread_rwlock_destroy(&m_rwl);  
  12. }  
  13.   
  14. void CRWLockImpl::ReadLockImpl()  
  15. {  
  16.     if (pthread_rwlock_rdlock(&m_rwl))   
  17.         cout<<"cannot lock reader/writer lock"<<endl;  
  18. }  
  19.   
  20. bool CRWLockImpl::TryReadLockImpl()  
  21. {  
  22.     int rc = pthread_rwlock_tryrdlock(&m_rwl);  
  23.     if (rc == 0)  
  24.         return true;  
  25.     else if (rc == EBUSY)  
  26.         return false;  
  27.     else  
  28.         cout<<"cannot lock reader/writer lock"<<endl;  
  29.   
  30.     return false;  
  31. }  
  32.   
  33. void CRWLockImpl::WriteLockImpl()  
  34. {  
  35.     if (pthread_rwlock_wrlock(&m_rwl))   
  36.         cout<<"cannot lock reader/writer lock"<<endl;  
  37. }  
  38.   
  39. bool CRWLockImpl::TryWriteLockImpl()  
  40. {  
  41.     int rc = pthread_rwlock_trywrlock(&m_rwl);  
  42.     if (rc == 0)  
  43.         return true;  
  44.     else if (rc == EBUSY)  
  45.         return false;  
  46.     else  
  47.         cout<<"cannot lock reader/writer lock"<<endl;  
  48.     return false;  
  49. }  
  50.   
  51. void CRWLockImpl::UnlockImpl()  
  52. {  
  53.     if (pthread_rwlock_unlock(&m_rwl))  
  54.         cout<<"cannot unlock reader/writer lock"<<endl;  
  55. }  

    下边是测试代码
[cpp] view plain copy
  1. // pthread_rwlock.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "RWLockImpl.h"  
  5.   
  6. //创建一个读写锁对象  
  7. CMyRWLock g_myRWLock;  
  8. volatile int g_counter = 0;  
  9.   
  10. //线程函数  
  11. void * StartThread(void *pParam)  
  12. {  
  13.     int lastCount = 0;  
  14.     for (int i = 0; i < 10000; ++i)  
  15.     {  
  16.         g_myRWLock.ReadLock();  
  17.         lastCount = g_counter;  
  18.         //在读锁域,两个线程不断循环交替访问全局变量g_counter  
  19.         for (int k = 0; k < 100; ++k)  
  20.         {  
  21.             if (g_counter != lastCount)   
  22.                 cout<<"the value of g_counter has been updated."<<endl;  
  23.             sleep(0);  
  24.         }  
  25.         g_myRWLock.Unlock();  
  26.   
  27.   
  28.         g_myRWLock.WriteLock();  
  29.         //在写锁域,只有一个线程可以修改全局变量g_counter的值  
  30.         for (int k = 0; k < 100; ++k)  
  31.         {  
  32.             --g_counter;  
  33.             sleep(0);  
  34.         }  
  35.         for (int k = 0; k < 100; ++k)  
  36.         {  
  37.             ++g_counter;  
  38.             sleep(0);  
  39.         }  
  40.         ++g_counter;  
  41.         if (g_counter <= lastCount)   
  42.             cout<<"the value of g_counter is error."<<endl;  
  43.         g_myRWLock.Unlock();  
  44.     }  
  45.   
  46.     return (void *)0;  
  47. }  
  48.   
  49. int main(int argc, char* argv[])  
  50. {  
  51.     pthread_t thread1,thread2;  
  52.     pthread_attr_t attr1,attr2;  
  53.   
  54.     //创建两个工作线程  
  55.     pthread_attr_init(&attr1);  
  56.     pthread_attr_setdetachstate(&attr1,PTHREAD_CREATE_JOINABLE);  
  57.     if (pthread_create(&thread1,&attr1, StartThread,0) == -1)  
  58.     {  
  59.         cout<<"Thread 1: create failed"<<endl;  
  60.     }  
  61.     pthread_attr_init(&attr2);  
  62.     pthread_attr_setdetachstate(&attr2,PTHREAD_CREATE_JOINABLE);  
  63.     if (pthread_create(&thread2,&attr2, StartThread,0) == -1)  
  64.     {  
  65.         cout<<"Thread 2: create failed"<<endl;  
  66.     }  
  67.   
  68.     //等待线程结束  
  69.     void *result;  
  70.     pthread_join(thread1,&result);  
  71.     pthread_join(thread2,&result);  
  72.   
  73.     //关闭线程,释放资源  
  74.     pthread_attr_destroy(&attr1);  
  75.     pthread_attr_destroy(&attr2);  
  76.   
  77.     cout<<"the g_counter = "<<g_counter<<endl;  
  78.   
  79.     int iWait;  
  80.     cin>>iWait;  
  81.   
  82.     return 0;  
  83. }  
   编译,运行
  

    运行结果与在Win32下用C++实现多线程读写锁的相同。

    欢迎转载,麻烦带上链接:http://blog.csdn.net/chexlong/article/details/7163233,谢谢合作!


你可能感兴趣的:(Linux平台用C++封装线程读写锁)