2

この単純なロギング クラスを見てください (ここでは関連する部分のみ)。

class Logger {
public:
    void log(string& msg){
        //lock for all instances
        cout << "[" << tag << "] " << msg;
        //unlock
    }
private:
     string tag;

};

Loggerクラス全体 (インスタンスではない) を同期して、 (異なるスレッド内の) の個別のインスタンスがcout順次 (一度にすべてではなく) に書き込む最も簡単な方法は何ですか?

4

4 に答える 4

7

ミューテックスを使用した通常の方法:

#include <mutex>

class Logger {
public:
    void log(string& msg)
    {
        // Lock for all instances
        std::lock_guard<std::mutex> lock(coutMutex);

        cout << "[" << tag << "] " << msg;

        // Unlocking happens automatically since the lock
        // gets destroyed here.
    }

private:
    string tag;
    static std::mutex coutMutex; // Don't forget to define this somewhere.
};
于 2013-02-18T08:26:16.883 に答える
3

短いバージョン: 同期ラッパー wrap を作成し、std::cout同期を使用しcoutて書き込みます。

長いバージョン:

#include <mutex>

template<typename T>
struct Synchronized {
  explicit Synchronized(T& t_):t(t_) {}

  template<typename Functor>
  auto operator()( Functor&& f ) const->decltype(f(t)) {
    std::lock_guard<std::mutex> guard(myMutex);
    return f(t);
  }
// I could implement these, but I'm lazy:
  Synchronized& operator=(Synchronized const&) = delete;
  Synchronized& operator=(Synchronized &&) = delete;
  Synchronized(Synchronized const&) = delete;
  Synchronized(Synchronized &&) = delete;
private:
  mutable T& t;
  mutable std::mutex myMutex;
};


// in "sync_cout.h"
extern Synchronized<std::ostream> sync_cout;

// in "sync_cout.cpp"
Synchronized<std::ostream> sync_cout(std::cout);

// In "logger.h"

// #include "sync_cout.h"
class Logger {
public:
  void log(string& msg){
    sync_cout( [&](std::ostream& os) {
      os << "[" << tag << "] " << msg;
    });
  }
private:
   string tag;

};

( Herbから盗まれました。上記の誤りはすべて私自身のものであり、Herb のものではありません。)

優れたパフォーマンスを得るために、上記のリンクにはノンブロッキングの非同期ラッパーも含まれています。

于 2013-02-18T15:15:03.130 に答える
2

それを行う最も簡単な方法:

class Logger {
public:
   void log(std::string& msg){
   //lock for all instances
   {  std::unique_lock<std::mutex> locker(_mut); // or std::lock_guard<std::mutex> locker(_mut);
      std::cout << "[" << tag << "] " << msg;
   } //unlock
private:
   std::string tag;
   static std::mutex _mut;
};
于 2013-02-18T08:28:18.917 に答える