簡體   English   中英

異步記錄器線程安全

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM