0

I have a non-blocking Timer class that:

  • counts down from whatever int the class is instantiated with
  • each new instance of the class waits for any timer that is currently running to first finish before they start counting down

Current Design of class:

class Timer{
private: 
  std::thread *thread;

public:
  Timer(const int &timer, std::mutex *mutex){
    this->thread = new std::thread(
        [&timer, mutex](){
          mutex->lock();
          std::cout<<"Counting to: "<<timer<<std::endl;
          for (int i=0; i < timer; i++) {
            std::cout<<i<<std::endl;
            sleep(1);
          }
          std::cout<<"Time is up"<<std::endl;
          mutex->unlock();
    });
  }

  ~Timer(){
    this->thread->join();
    delete this->thread;
  }
};

I am calling it from main with this:

int main() {
  std::mutex mutex;
  Timer time(3, &mutex);
  Timer newTime(9, &mutex);
  //Do something else in the meantime ...
  return 0;
}

Quesion:

I would like to simplify the main by internalising the mutex as a static variable of the class. Something like this:

  • a simpler main
int main() {
  Timer time(3);
  Timer newTime(9);
  //Do something else in the meantime ...
  return 0;
}
  • a more representative Timer class:
class Timer{
private: 
  std::thread *thread;
  static std::mutex timerMutex;

public:
  Timer(const int &timer){
    this->thread = new std::thread(
        [&timer, this](){
          timerMutex.lock();
          std::cout<<"Counting to: "<<timer<<std::endl;
          for (int i=0; i < timer; i++) {
            std::cout<<i<<std::endl;
            sleep(1);
          }
          std::cout<<"Time is up"<<std::endl;
          timerMutex.unlock();
    });
  }

  ~Timer(){
    this->thread->join();
    delete this->thread;
  }
};
  • How can I do this ?

Current Error:

 error: linker command failed with exit code 1
cstml
  • 350
  • 1
  • 12
  • Presumably the linker error is an undefined symbol for `Timer::timerMutex`? – Alan Birtles Nov 22 '20 at 14:38
  • If I replace the static definition with: `Timer::timerMutex` I get: `error: extra qualification on member 'timerMutex' static std::mutex Timer::timerMutex;` so the answer from [link](https://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member) does not seem to work – cstml Nov 22 '20 at 14:44
  • I see, I must create the `Timer::timerMutex` outside the class. Interesting that instantiating a class element doesn't instantiate the static elements. thank you – cstml Nov 22 '20 at 14:54
  • `inline static` in the class declaration works in C++17 without the need to define the variable elsewhere. – Paul Sanders Nov 22 '20 at 14:56
  • oh, that's interesting! Thanks for sharing. @PaulSanders – cstml Nov 23 '20 at 16:05

0 Answers0