C++線程與并發(Ice3.4.2)
概述
Ice伺服器是多線程模型的。在涉及資源的通路和操作的時候将要考慮同步通路機制。
Ice線程庫提供了一些與線程有關的抽象:
互斥體,遞歸互斥體,讀寫遞歸互斥體,監控器,一個線程抽象,允許開發者建立,控制,銷毀線程。
1.互斥體(The Mutex Class)
1.1)互斥體的定義
IceUtil::Mutex類提供了簡單的非遞歸互斥機制,其定義如下:
[cpp]
view plain
copy
- namespaceIceUtil {
- enum
- class
- public:
- Mutex();
- Mutex(MutexProtocol p);
- ~Mutex();
- void lock() const; /*lock 函數嘗試擷取互斥體。如果互斥體已經鎖住,它就會挂起發出調用的線程(calling thread),直到互斥體變得可用為止*/
- bool tryLock() const;/*trylock函數嘗試擷取互斥體。如果互斥體未被鎖住則傳回true,否則直接傳回false*/
- void unlock() const; /*嘗試解除互斥體的加鎖*/
- typedef
- typedef
- };
1.2)使用互斥類
假設有一個FileSystem類和write的函數如下:
[cpp]
view plain
copy
- #include<IceUtil/Mutex.h>
- namespaceFilesystem {
- class FileI : virtual public
- virtual public
- public:
- // ...
- private:
- Lines _lines;
- //互斥鎖
- };
- // ...
- }
- void Filesystem::FileI::write(const Filesystem::Lines &text,const
- {
- _fileMutex.lock();
- _lines = text;
- //if(somecondition)return ;
- _fileMutex.unlock();
- }
然而這種加入互斥機制的方法并不好,例如對互斥體加鎖了但在函數傳回時并沒有實作解鎖操作,這種情況下就引發死鎖情況。
是以我們建議使用Ice提供的兩個助手類Lock和TryLock,如下:
[cpp]
view plain
copy
- voidSomeClass::someFunction(/* params here... */)
- {
- // 對mutex對象加鎖
- // Lots of complexcode here...
- if
- return; // No problem
- }
- //...
- } // 此處調用Mutex類對象的析構函數,同時會解除互斥鎖的加鎖狀态。
2.遞歸互斥體(The C++ RecMutex Class)
上面所介紹的互斥體是非遞歸性質的,也就是說他們不能被多次加鎖,即使是已經擁有該所的線程也不行。這樣會給一些情況帶來不便
[cpp]
view plain
copy
- IceUtil::Mutex_mutex;
- void
- {
- IceUtil::Mutex::Lock lock(_mutex);
- // ...
- }
- void
- {
- IceUtil::Mutex::Locklock(_mutex);
- // Deadlock!
- // ...
- }
為了解決這個問題,Ice同樣也提供了遞歸互斥鎖,如下示例:
[cpp]
view plain
copy
- #include <IceUtil/RecMutex.h>
- IceUtil::RecMutex _mutex; // Recursive mutex
- void
- {
[cpp]
view plain
copy
- //如果該互斥體已被其他線程加鎖,那麼該線程将會被挂起
- // ...
- }
- void
- {
- IceUtil::RecMutex::Lock lock(_mutex);
- // Fine
- //...
- }
3. 讀寫遞歸互斥體(The RWRecMutex Class)
由于遞歸互斥體無論是在讀取還是寫操作的情況下,都是将其并發線程通路序列化。但是讀取資源的線程并不會修改所通路的内容;是以讓多個讀取線程并行擁有互斥體,而同一時刻隻能有一個寫入的線程擷取互斥體。
下面是該讀寫互斥類的定義:
[cpp]
view plain
copy
- namespaceIceUtil {
- class
- public:
- void readLock() const;
- bool tryReadLock() const;
- bool timedReadLock(const Time&) const;
- void writeLock() const;
- bool tryWriteLock() const;
- bool timedWriteLock(const Time&) const;
- void unlock() const;
- void upgrade() const;
- bool timedUpgrade(const Time&) const;
- typedef
- typedefTryRLockT<RWRecMutex> TryRLock;
- typedef
- typedefTryWLockT<RWRecMutex> TryWLock;
- };
- }
4.定時鎖
讀寫鎖提供了一些可使用逾時的成員函數。等待的時間量是通過IceUtil::Time類的執行個體指定的。
5.監控器(The Monitor)
5.1 Monitor類定義
Monitor類在IceUtil::Monitor中定義,如下所示:
[cpp]
view plain
copy
- namespace
- template <class
- class
- public:
- void lock() const;
- void unlock() const;
- bool tryLock() const;
- void wait() const;
- bool timedWait(constTime&) const; //這個函數挂起調用它的線程,直到指定的時間流逝.如果在逾時之前喚醒被挂起的線程,
- //這個調用就傳回true;否則傳回false。
- void
- void
- typedefLockT<Monitor<T> > Lock;
- typedefTryLockT<Monitor<T> > TryLock;
- };
- }