Как управлять состоянием переменной в синглтон-классе? - PullRequest
2 голосов
/ 24 сентября 2019

Я пытаюсь создать программу-регистратор приложений в среде C ++ для Linux / UNIX, которая эффективно обрабатывает многопоточную среду.Проблема, с которой я сейчас сталкиваюсь, связана с синглтон-классом, позвольте мне сначала показать вам код, а затем я спрошу вопрос, который я копал за последние несколько дней -

class Logger {

private:
  int mNumber;


public:
  static Logger& getInstance(int num){

     static Logger object;

     /* 
       I have already solved the problem for single threaded application, below is what I was doing
     */   
     object.setNumber(num);

     /*
       But I can not do the above in multi thread application, even with lock( I prefer pthread) mutexes and semaphores.
     */
     return object;
  }

  void debug(const char* str){
     std::cout << "Num : "  << mNumber << " :: Message : " << str << std::endl;
  }

private:

  void setNumber(const int num){
    this->mNumber = value;
  }  
};  

#define logMe   Logger::getInstance(__LINE__)

void* threadOne(void* args){

   while(true){
      logMe.debug("I am from threadOne");
   }
   return (void*) nullptr;
}// end

int main(int argc, char** argv){

    logMe.debug("Works with single threaded application.");
   /*
     1) Correct me if I am wrong, the above gets expand to
        Logger::getInstance(__LINE__).debug("value");
     2) Now that is the problem, somehow, I want this value to pass to debug method. 
   */

   // This is what I have been trying to do-
   pthread_t tid;
   pthread_create(&tid, nullptr, threadOne, nullptr);

   while (true){
      logMe.debug("I am from Main");
      usleep(2000);     // This is not neccesarry just to check while debugging.
   }
   exit (EXIT_SUCCESS);
}// end

Проблема:

Почему-то я хочу вести запись номера строки и сообщения одновременно.Я не уверен, есть ли другие модели, которые могут спасти мою жизнь.Любая помощь в любом направлении будет действительно полезна.СПАСИБО заранее.

1 Ответ

0 голосов
/ 24 сентября 2019

Отделите класс, который выполняет работу, от класса, который содержит значение:

struct Logger {
  struct Line {
    Logger &log;
    int n;
    void debug(const char *s)
    {log.debug(n,s);}
  };

  Line at(int n) {return {*this,n};}

private:
  void debug(int n,const char *s)
  {std::cout << "Num : "  << n << " :: Message : " << s << std::endl;}
};

. Вы можете сделать Logger другом Line, чтобы не подвергать действию вспомогательного конструктора, но любой может передатьчто угодно, до at.

Обратите внимание, что Logger::debug не использует this;если это так в реальном случае, сделайте его static (или вовсе не функцией-членом), и вы можете упростить Line и избежать одиночного перехода, который является основным выигрышем (особенно в многопоточной среде).

...