如果我必須在C++中編寫單例類,我將使用一個靜態變量,即私有構造函數&一個返回類的對象的公共靜態函數。但是在多線程環境中,代碼會有問題。爲了避免多個線程同時訪問同一個變量,是Boost線程最佳的同步機制嗎?我的意思是在資源上設置/取消鎖定/互斥鎖。在C++標準庫中還有其他內置內容,我不需要下載提升,編譯內容等?我聽說過C++ Ox,但不太瞭解。Singleton Synchronization C++
回答
C++ 98/03根本不支持線程。如果您使用的是C++ 98或03編譯器,那麼您幾乎堅持使用Boost或某些(或多或少)特定於操作系統的操作系統,比如pthread或Win32的線程原語。
C++ 11有一個相當完整的線程支持庫,互斥鎖,鎖,線程本地存儲等
我覺得有必要指出的是,然而,它可能是更好的備份和多做一點思考你是否需要/想要一個Singleton。說得很好,單身模式在很大程度上已經失寵。
編輯:重讀這個,我跳過了一個我想說的事情:至少當我使用它們時,任何/所有單例都在任何輔助線程啓動之前完全初始化。這使得初始化時對線程安全性的擔憂完全沒有實際意義。我想在你啓動輔助線程之前可能會有一個你不能初始化的單例,所以你需要處理這個問題,但至少從它的角度來說,我覺得這是一個相當不尋常的例外, /如果絕對必要。
對於我實現使用C++ 11單身最好的辦法是:
class Singleton
{
public:
static Singleton & Instance()
{
// Since it's a static variable, if the class has already been created,
// It won't be created again.
// And it **is** thread-safe in C++11.
static Singleton myInstance;
// Return a reference to our instance.
return myInstance;
}
// delete copy and move constructors and assign operators
Singleton(Singleton const&) = delete; // Copy construct
Singleton(Singleton&&) = delete; // Move construct
Singleton& operator=(Singleton const&) = delete; // Copy assign
Singleton& operator=(Singleton &&) = delete; // Move assign
// Any other public methods
protected:
Singleton()
{
// Constructor code goes here.
}
~Singleton()
{
// Destructor code goes here.
}
// And any other protected methods.
}
這是一個C++ 11功能,但用這種方式,您可以創建一個線程安全的辛格爾頓。根據新標準,再也不需要關心這個問題了。對象初始化將僅由一個線程完成,其他線程將一直等待完成。或者你可以使用std :: call_once。
如果你想獨佔訪問單身人士的資源,你必須在這些功能上使用鎖。
不同類型的鎖:
使用atomic_flg_lck:
class SLock
{
public:
void lock()
{
while (lck.test_and_set(std::memory_order_acquire));
}
void unlock()
{
lck.clear(std::memory_order_release);
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck.clear();
}
private:
std::atomic_flag lck;// = ATOMIC_FLAG_INIT;
};
使用原子:
class SLock
{
public:
void lock()
{
while (lck.exchange(true));
}
void unlock()
{
lck = true;
}
SLock(){
//lck = ATOMIC_FLAG_INIT;
lck = false;
}
private:
std::atomic<bool> lck;
};
使用互斥:
class SLock
{
public:
void lock()
{
lck.lock();
}
void unlock()
{
lck.unlock();
}
private:
std::mutex lck;
};
只是爲了的Windows:
class SLock
{
public:
void lock()
{
EnterCriticalSection(&g_crit_sec);
}
void unlock()
{
LeaveCriticalSection(&g_crit_sec);
}
SLock(){
InitializeCriticalSectionAndSpinCount(&g_crit_sec, 0x80000400);
}
private:
CRITICAL_SECTION g_crit_sec;
};
的原子和和atomic_flg_lck保持在一個旋轉計數的線程。 互斥體只是睡覺的線程。如果等待時間太長,可能會更好地睡眠線程。最後一個「CRITICAL_SECTION」將線程保持在旋轉計數直到消耗時間,然後線程進入休眠狀態。
如何使用這些關鍵部分?
unique_ptr<SLock> raiilock(new SLock());
class Smartlock{
public:
Smartlock(){ raiilock->lock(); }
~Smartlock(){ raiilock->unlock(); }
};
使用raii成語。構造函數鎖定關鍵部分和析構函數以解鎖它。
例
class Singleton {
void syncronithedFunction(){
Smartlock lock;
//.....
}
}
該實現是線程安全和異常安全的,因爲可變鎖被保存在堆棧中,以便當所述功能範圍結束(的功能或異常結束)的析構函數將被調用。
我希望你覺得這有幫助。
謝謝!
- 1. ThreadStatic和Synchronization
- 2. Synchronization Forms.Timer和Diagnostics.Stopwatch
- 3. Objective-c singleton baseclass
- 4. NHibernate - Session Singleton C#
- 5. singleton in objective c
- 6. select socket call send and recv synchronization
- 7. Monitor Synchronization如何工作?
- 8. Objective-C Singleton超類?
- 9. singleton class in objective-C
- 10. 目標C的Singleton
- 11. objective-c如何使用singleton?
- 12. C++ Threadsafe Singleton(NOT FOR INIT)
- 13. Singleton模式C++錯誤
- 14. C++ boost線程ID和Singleton
- 15. C++ Singleton未定義引用
- 16. C++ Singleton線程問題
- 17. Synchronization如何在StringBuffer中工作?
- 18. Singleton with multiserver
- 19. 當Singleton不是Singleton?
- 20. Spring bean singleton vs singleton pattern
- 21. 匕首2 Singleton vs Real Singleton
- 22. Singleton類
- 23. Singleton Destructors
- 24. 對Singleton :: Singleton()的未定義引用()
- 25. Singleton模式
- 26. 基於Jon Skeet的Singleton的Simpleton Singleton
- 27. C#Singleton對象的許多實例
- 28. 使用Singleton的Ruby C擴展
- 29. 澄清一個Objective-C的Singleton實例
- 30. 使用序列化打破Singleton C#
我還沒有看到任何暗示單身模式在實際從業者中不受歡迎的事情。 (當然,它從來沒有被廣泛使用過,只是在適當的時候,這種情況並不常見) – 2012-04-05 08:44:05
我見過許多'Singleton's,但沒有一個是必需的。只需製作一個並傳遞給它。 – 2012-04-05 09:42:50
粗略地說:一個'Singleton'通常是一個設計錯誤。雖然...我同意記錄方案很方便(遠比在每個函數中傳遞Logger對象更重要)。 – 2012-04-05 11:50:55