I wrote this class today, but I am trying to figure out how to make it more accurate. I pass in seconds and multiply by 1000 to make it milliseconds, and the time does not line up. I need the ability to have multiple timers, so using `timer_gettime()`, which limits one clock per process, is not an option. Also note I borrowed my idea from free glut.

Please feel free to leave general comments on style, but please focus more on how to improve the accuracy of the timer.

    #include "TimerManager.h"
    #include <iostream>
    
    void func1(int id)
    {
      std::cout << "I was called with " << std::endl;
    }
    
    void func2(int id)
    {
      std::cout << "I was called too ))))))))))))))))))))))))))))))))))))))))))))))))))))))))))" << std::endl;
    }
    
    int main(int argc, char *argv[])
    {
      TimerManager t;
      t.addTimer(6, func1);
      t.addTimer(2, func2);
      while(true) {
        t.start();
      }
      return 0;
    }

---

    #ifndef TIMERMANAGER_H_
    #define TIMERMANAGER_H_
    
    #include <stdlib.h>
    #include <iostream>
    #include <pthread.h>
    #include <list>
    
    extern "C" {
      void *create_pthread(void *data);
    }
    
    class TimerManager {
    public:
      TimerManager();
      ~TimerManager();
      void start();
      void stop();
      void addTimer(long usec, void (*callback)(int id));
    private:
      class Timer  
      {
      public:
        Timer(long usec, void (*callback)(int)) :
          duration(usec),
          callback(callback),
          start(0)
        {    
        }   
        bool operator ==(Timer other)
        {   
          if ((this->callback == other.callback) && (this->duration == other.duration)) {
            return true;
          }   
          return false;
        }   
        long duration;
        void (*callback)(int);
        long start;
      };  
      std::list<Timer> m_timers;
      pthread_t m_timer_thread;
      Timer setUpTimer(long usec, void (*callback)(int id));
      friend void *create_pthread(void *data);
      void run();
      bool go; 
    };
    
    #endif

---

    #include <algorithm>
    #include <iterator>
    #include <sys/time.h>
    #include "TimerManager.h"
    
    extern "C" void *create_pthread(void *data)
    {
      TimerManager *thread_timer_manager = static_cast<TimerManager *>(data);
      thread_timer_manager->run();
      return data;
    }
    
    TimerManager::TimerManager() :
        go(false)
    {
      int thread_creation = pthread_create(&m_timer_thread, NULL, create_pthread, this);
      if(thread_creation != 0) {
        std::cerr << "Failed to create thread" << std::endl;
        return;
      } else {
        std::cout << "The status flag is " << thread_creation << std::endl;
      }
    }
    
    TimerManager::~TimerManager() 
    {
    }
    
    void TimerManager::run() 
    {
      struct timeval l_tv;
      while(true) {
        if (go) {
          typedef std::list<Timer>::iterator li; 
          li begin = m_timers.begin();
          li end = m_timers.end();
          int item = 0;
          for(;begin != end; ++begin) {
            gettimeofday(&l_tv, NULL);
            long elapsed_time = (l_tv.tv_usec - begin->start);
            sleep(1);
            if (elapsed_time >= begin->duration) {
              //std::cout << "Status of timer " << item << " is " << elapsed_time << " > " << begin->duration << std::endl;
              begin->callback(item);
              gettimeofday(&l_tv, NULL);
              begin->start = l_tv.tv_usec;
            } else {
              //std::cout << "Status of timer " << item << " is " << elapsed_time << " < " << begin->duration << std::endl;
            }   
            item++;
          }   
        }   
      }
    }
    
    void TimerManager::start()
    {
      go = true;
    }
    
    oid TimerManager::stop() 
    {
      go = false;
    }
    
    TimerManager::Timer TimerManager::setUpTimer(long usec, void (*callback)(int id))
    {
      struct timeval l_tv;
      gettimeofday(&l_tv, NULL);
      Timer l_t(usec * 100, callback);
      l_t.start = l_tv.tv_usec;
      std::cout << "Timer created with a values of START: " << l_t.start << " CALLBACK: " << &l_t.callback << " DURATION: " << l_t.duration << std::endl;
      return l_t;
    }
    
    void TimerManager::addTimer(long usec, void (*callback)(int id))
    {
      Timer insert = setUpTimer(usec, callback);
      typedef std::list<Timer>::iterator li;
      li begin = m_timers.begin();
      li end = m_timers.end();
      for(;begin != end; ++begin) {
        if (*begin == *end) {
          return;
        }
      }
      m_timers.push_back(insert);
    }


----------------
#*Update*: Changes after reading answers.

Here is the updated code,

    #include "TimerManager.h"
    #include <iostream>
    #include <fstream>
    #include <sys/time.h>
    
    extern "C"
    void func1(int id)
    {
      struct timeval l_tv;
      gettimeofday(&l_tv, NULL);
      std::cout << "I was called (1) @ " << l_tv.tv_usec << std::endl;
    }
    
    extern "C"
    void func2(int id)
    {
      struct timeval l_tv;
      gettimeofday(&l_tv, NULL);
      std::cout << "I was called (2) @ " << l_tv.tv_usec << std::endl;
    }
    
    int main(int, char *[])
    {
      TimerManager t;
      t.addTimer(1000000 / 2, func1);
      t.addTimer(1000000 * 4, func2);
      t.start();
      while(true) {
        sleep(1);
      }
      return 0;
    }

---

    #ifndef TIMERMANAGER_H_
    #define TIMERMANAGER_H_
    
    #include <stdlib.h>
    #include <iostream>
    #include <pthread.h>
    #include <list>
    
    extern "C" {
      void *create_pthread(void *data);
    }
    
    class TimerManager {
    public:
      TimerManager();
      ~TimerManager();
      void start();
      void stop();
      void addTimer(long usec, void (*callback)(int id));
    private:
      class Timer  
      {
      public:
        Timer(long usec, void (*callback)(int)) :
          duration(usec),
          callback(callback),
          start(0)
        {      
        }
        bool operator ==(Timer other)
        {
          if ((this->callback == other.callback) && (this->duration == other.duration)) {
            return true;
          }
          return false;
        }
        void operator =(Timer other)
        {
          duration = other.duration;
          callback = other.callback;
          start = other.start;
        }
        suseconds_t duration;
        void (*callback)(int);
        suseconds_t start;
      };
      Timer setUpTimer(long micro_duration, void (*callback)(int id));
      friend void *create_pthread(void *data);
      void run();
      bool m_bRunning;
      bool m_bGo;
      long m_lMinSleep;
      std::list<Timer> m_cTimers;
      pthread_t m_tTimerThread;
      pthread_cond_t m_tGoLockCondition;
      pthread_mutex_t m_tGoLock;
    };
    
    #endif

---

    #include <algorithm>
    #include <iterator>
    #include <sys/time.h>
    #include "TimerManager.h"
    
    extern "C" void *create_pthread(void *data)
    {
      TimerManager *thread_timer_manager = static_cast<TimerManager *>(data);
      thread_timer_manager->run();
      return data;
    }
    
    TimerManager::TimerManager() :
      m_bRunning(false),
      m_bGo(false),
      m_lMinSleep(0)
    {
      int mutex_creation = pthread_mutex_init(&m_tGoLock, NULL);
      if(mutex_creation != 0) {
        std::cerr << "Failed to create mutex" << std::endl;                                   // Use RAII if resource acquisition fails
        return;
      }
    
      int mutex_cond_creation = pthread_cond_init(&m_tGoLockCondition, NULL);
      if(mutex_cond_creation != 0) {
        std::cerr << "Failed to create condition mutex" << std::endl;                         // Use RAII if resource acquisition fails
        return;
      }
    
      int thread_creation = pthread_create(&m_tTimerThread, NULL, create_pthread, this);      // On success call create_pthread to start tiemr loop
      if(thread_creation != 0) {
        std::cerr << "Failed to create thread" << std::endl;                                  // Use RAII if resource acquisition fails
        return;
      }
      m_bRunning = true;
    }
    
    TimerManager::~TimerManager() 
    {
        pthread_mutex_lock(&m_tGoLock);                                                       // m_bRunning access on other thread
        m_bRunning = false;
        pthread_mutex_unlock(&m_tGoLock);
        void *result;
        pthread_join(m_tTimerThread, &result);                                                // Do not let calling thread exit before deleting
        pthread_mutex_destroy(&m_tGoLock);                                                    // Now destroy the mutex (release resources)
        pthread_cond_destroy(&m_tGoLockCondition);
    }
    
    void TimerManager::run() 
    {
      pthread_mutex_lock(&m_tGoLock);                                                         // Timers run on seperate thread
      while(m_bRunning) {                                                                     // While timer manager exists
        while (!m_bGo) {                                                                      // While timer manager told to run
          pthread_cond_wait(&m_tGoLockCondition, &m_tGoLock);                                 // Set in the start() member function
        }
        pthread_mutex_unlock(&m_tGoLock);                                                     // Once timer unlocked and mutex released
        if (!m_bRunning) {                                                                    // Make sure timer manager not out of scope
          break;
        }
    
        struct timeval l_tv;
        usleep(std::max(0l, m_lMinSleep));
        gettimeofday(&l_tv, NULL);                                                            // System call to get time of day
        m_lMinSleep = 0;                                                                      // Used to sleep if no timer to go off soon
        long l_lMin = 0;                                                                      // Used if timer goes off to get actual Min sleep
        for(std::list<Timer>::iterator it = m_cTimers.begin(); it != m_cTimers.end(); ++it) { // Iterate over timers to see which one is going off
          TimerManager::Timer l_oTimer = *it;                                                 // Obtain a copy of the timer
          long elapsed_time = ((l_tv.tv_sec * 1000000 + l_tv.tv_usec) - (l_oTimer.start));    // Calcuate the elapsed time from the start of timer X
          l_lMin = elapsed_time - l_oTimer.duration;                                          // Minimum time you can sleep in loop
          if (elapsed_time >= l_oTimer.duration) {                                            // If time passed is greater than or equal to duration: THEN
            l_lMin = l_oTimer.duration;                                                       // The minimum you can wait is possibly the entire duration of that timer
            l_oTimer.callback(0);                                                             // Call the call back
            gettimeofday(&l_tv, NULL);                                                        // After callback called...
            it->start = (l_tv.tv_sec * 1000000) + l_tv.tv_usec;                               // Start the timer over again
          }
          m_lMinSleep = std::min(m_lMinSleep, l_lMin);                                        // Find the actual minumum time you can sleep to not lock
        }
      }
    }
    
    void TimerManager::start()
    {
      pthread_mutex_lock(&m_tGoLock);                                                         // Go flag accessed from another thread
      m_bGo = true;
      pthread_cond_signal(&m_tGoLockCondition);
      pthread_mutex_unlock(&m_tGoLock);
    }
    
    void TimerManager::stop() 
    {
      pthread_mutex_lock(&m_tGoLock);                                                         // Go flag accessed from another thread
      m_bGo = false;
      pthread_mutex_unlock(&m_tGoLock);
    }
    
    TimerManager::Timer TimerManager::setUpTimer(long micro_duration, void (*callback)(int id))
    {
      struct timeval l_tv;
      gettimeofday(&l_tv, NULL);                                                              // System call to get the ms and sec since Epoch0
      Timer l_oTimer(micro_duration, callback);                                               // Create a timer
      l_oTimer.start = (l_tv.tv_sec * 1000000) + l_tv.tv_usec;                                // Tell the timer when to start
      return l_oTimer;                                                                        // Return a copy to addTimer
    }
    
    void TimerManager::addTimer(long usec, void (*callback)(int id)) 
    {
      pthread_mutex_lock(&m_tGoLock);                                                         // Tell object to wait till timer inserted
      Timer insert = setUpTimer(usec, callback);
      for (std::list<Timer>::iterator it = m_cTimers.begin(); it != m_cTimers.end(); ++it) {
        if (*it == insert) {                                                                  // Return if timer callback and duration the same
            return;
        }
      }
      m_cTimers.push_back(insert);                                                            // If no duplicate timers found then insert into list
      pthread_mutex_unlock(&m_tGoLock);                                                       // Tell object it is okay to proceed
    }