在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虚拟机中编译,测试通过。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
//RWLockImpl.h #ifndef _RWLockImpl_Header #define _RWLockImpl_Header #include <iostream> #include <pthread.h> #include <errno.h> #include <assert.h> using namespace std; /* 读写锁允许当前的多个读用户访问保护资源,但只允许一个写读者访问保护资源 */ //----------------------------------------------------------------- class CRWLockImpl { protected: CRWLockImpl(); ~CRWLockImpl(); void ReadLockImpl(); bool TryReadLockImpl(); void WriteLockImpl(); bool TryWriteLockImpl(); void UnlockImpl(); private: pthread_rwlock_t m_rwl; }; //----------------------------------------------------------------- class CMyRWLock: private CRWLockImpl { public: //创建读/写锁 CMyRWLock(){}; //销毁读/写锁 ~CMyRWLock(){}; //获取读锁 //如果其它一个线程占有写锁,则当前线程必须等待写锁被释放,才能对保护资源进行访问 void ReadLock(); //尝试获取一个读锁 //如果获取成功,则立即返回true,否则当另一个线程占有写锁,则返回false bool TryReadLock(); //获取写锁 //如果一个或更多线程占有读锁,则必须等待所有锁被释放 //如果相同的一个线程已经占有一个读锁或写锁,则返回结果不确定 void WriteLock(); //尝试获取一个写锁 //如果获取成功,则立即返回true,否则当一个或更多其它线程占有读锁,返回false //如果相同的一个线程已经占有一个读锁或写锁,则返回结果不确定 bool TryWriteLock(); //释放一个读锁或写锁 void Unlock(); private: CMyRWLock(const CMyRWLock&); CMyRWLock& operator = (const CMyRWLock&); }; inline void CMyRWLock::ReadLock() { ReadLockImpl(); } inline bool CMyRWLock::TryReadLock() { return TryReadLockImpl(); } inline void CMyRWLock::WriteLock() { WriteLockImpl(); } inline bool CMyRWLock::TryWriteLock() { return TryWriteLockImpl(); } inline void CMyRWLock::Unlock() { UnlockImpl(); } #endif |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
//RWLockImpl.cpp #include "RWLockImpl.h" CRWLockImpl::CRWLockImpl() { if (pthread_rwlock_init(&m_rwl, NULL)) cout<<"cannot create reader/writer lock"<<endl; } CRWLockImpl::~CRWLockImpl() { pthread_rwlock_destroy(&m_rwl); } void CRWLockImpl::ReadLockImpl() { if (pthread_rwlock_rdlock(&m_rwl)) cout<<"cannot lock reader/writer lock"<<endl; } bool CRWLockImpl::TryReadLockImpl() { int rc = pthread_rwlock_tryrdlock(&m_rwl); if (rc == 0) return true; else if (rc == EBUSY) return false; else cout<<"cannot lock reader/writer lock"<<endl; return false; } void CRWLockImpl::WriteLockImpl() { if (pthread_rwlock_wrlock(&m_rwl)) cout<<"cannot lock reader/writer lock"<<endl; } bool CRWLockImpl::TryWriteLockImpl() { int rc = pthread_rwlock_trywrlock(&m_rwl); if (rc == 0) return true; else if (rc == EBUSY) return false; else cout<<"cannot lock reader/writer lock"<<endl; return false; } void CRWLockImpl::UnlockImpl() { if (pthread_rwlock_unlock(&m_rwl)) cout<<"cannot unlock reader/writer lock"<<endl; } |
下边是测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
// pthread_rwlock.cpp : 定义控制台应用程序的入口点。 // #include "RWLockImpl.h" //创建一个读写锁对象 CMyRWLock g_myRWLock; volatile int g_counter = 0; //线程函数 void * StartThread(void *pParam) { int lastCount = 0; for (int i = 0; i < 10000; ++i) { g_myRWLock.ReadLock(); lastCount = g_counter; //在读锁域,两个线程不断循环交替访问全局变量g_counter for (int k = 0; k < 100; ++k) { if (g_counter != lastCount) cout<<"the value of g_counter has been updated."<<endl; sleep(0); } g_myRWLock.Unlock(); g_myRWLock.WriteLock(); //在写锁域,只有一个线程可以修改全局变量g_counter的值 for (int k = 0; k < 100; ++k) { --g_counter; sleep(0); } for (int k = 0; k < 100; ++k) { ++g_counter; sleep(0); } ++g_counter; if (g_counter <= lastCount) cout<<"the value of g_counter is error."<<endl; g_myRWLock.Unlock(); } return (void *)0; } int main(int argc, char* argv[]) { pthread_t thread1,thread2; pthread_attr_t attr1,attr2; //创建两个工作线程 pthread_attr_init(&attr1); pthread_attr_setdetachstate(&attr1,PTHREAD_CREATE_JOINABLE); if (pthread_create(&thread1,&attr1, StartThread,0) == -1) { cout<<"Thread 1: create failed"<<endl; } pthread_attr_init(&attr2); pthread_attr_setdetachstate(&attr2,PTHREAD_CREATE_JOINABLE); if (pthread_create(&thread2,&attr2, StartThread,0) == -1) { cout<<"Thread 2: create failed"<<endl; } //等待线程结束 void *result; pthread_join(thread1,&result); pthread_join(thread2,&result); //关闭线程,释放资源 pthread_attr_destroy(&attr1); pthread_attr_destroy(&attr2); cout<<"the g_counter = "<<g_counter<<endl; int iWait; cin>>iWait; return 0; } |
编译,运行
运行结果与在Win32下用C++实现多线程读写锁的相同。
发表评论
要发表评论,您必须先登录。