[英]async logger thread safe
我寫了一個簡單的記錄器,我有一個問題。
pthread_mutex_t l_mutex = PTHREAD_MUTEX_INITIALIZER;
class logger
{
public:
logger() { }
template<typename T>
logger& operator<<(const T& t)
{
pthread_mutex_lock(&l_mutex);
std::cout << t << std::flush;
pthread_mutex_unlock(&l_mutex);
return *this;
}
protected:
};
static const unsigned char endline = '\n';
static logger log;
然而,當我從兩個線程使用記錄器時,它會做它不應該做的事情。 調用;
主題#1
log << "Hello " << 1;
主題#2
log << "Goodbye " << 2;
由於 operator<< 的實現方式,輸出被交錯。 我如何才能自然地使用 << 並且讓它本質上是原子的,而不是
你好 2 再見 1
我們保證得到
你好 1 再見 2
提前致謝。 是否有靈丹妙葯或需要新方法?
謝謝
G
使用輔助對象。
更改現有的<<
重載方法以返回輔助對象,例如:
template<typename T>
loggerHelper operator<<(const T& t)
{
return loggerHelper{} << t;
}
您的loggerHelper
類必須具有以下屬性:
它的構造函數應該獲取互斥鎖。 析構函數將解鎖互斥鎖。 普通的 RAII 設計模式,但有一個額外的扭曲:
對象必須正確且准確地實現移動語義。 移出對象實例不會釋放前面提到的互斥鎖,移到對象將對此負責。 復制構造函數和賦值運算符必須是delete
d。
該對象使用std::cout
實現“真正的” <<
運算符重載並返回*this
。 這將觸發移動語義,並將釋放互斥鎖的“燙手山芋”傳遞給下一個<<
運算符調用,或者如果沒有,則最終銷毀路盡頭助手類實例。
如果所有這些步驟都正確完成,那么我希望最終結果將是主logger
對象上的互斥鎖被獲取一次,並且在所有菊花鏈<<
運算符完成其職責之前不會釋放。
第一個<<
運算符由上面的原始<<
運算符啟動,並且它們都被真正地處理,由助手對象的<<
運算符重載,移動語義負責保留底層互斥鎖,並釋放它在末尾。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.