Простой и удобный способ организации работы с таймерами для множества однотипных объектов одновременно.
Используемые системные вызовы: timer_create, timer_settime, timer_gettime.
1. Создадим базовый виртуальный класс, приблизительно такой:
class ITimer { public: ITimer(); ~ITimer(); void CreateTimer(); void DestroyTimer(); void On(time_t vTime); void On(time_t vTime,long lNanoSec); time_t IsActive(); time_t IsEndTime(); void Off(); void Waiting(); virtual bool DoAction()=0; sigset_t psig_maskFirst; siginfo_t psig_infoFirst; struct sigevent sevFirst; struct sigaction saFirst; };
Функция CreateTimer() может быть приблизительно такая:
void ITimer::CreateTimer() { int ilErrno; saFirst.sa_flags = SA_SIGINFO; saFirst.sa_sigaction = handler_timer; if (sigaction(SIGRTMIN, &saFirst, NULL) == -1) { ilErrno = errno; fprintf(stderr," error. sigaction %s\n", getpid(),strerror(ilErrno)); } sevFirst.sigev_notify = SIGEV_SIGNAL; sevFirst.sigev_signo = SIGRTMIN; sevFirst.sigev_value.sival_ptr = this; if (timer_create(CLOCK_REALTIME, &sevFirst, (void **)&timerFirstId) == -1) { ilErrno = errno; fprintf(stderr,"error timer_create. %s\n", strerror(ilErrno)); } }
Особое внимание здесь надо обратить на строку:
sevFirst.sigev_value.sival_ptr = this;
2. Подготовим обработчик сигнала SIGRTMIN:
static void handler_timer(int sig, siginfo_t *si, void *uc) { ITimer* opITimer; opITimer = (ITimer*)si->si_int; opITimer->DoAction(); }
3. Подготовим классы, наследующие этот базовый класс ITimer.
class CUser:public ITimer { public: CUser(); ~CUser(); virtual bool DoAction(); }; //--------------------------------- bool CUser::DoAction() { fprintf(stdout," User:: Hello Word!!! \n"); } class CAbonent:public ITimer { public: CAbonent(); ~CAbonent(); virtual bool DoAction(); }; //--------------------------------- bool CAbonent::DoAction() { fprintf(stdout," Abonent:: Hello Word!!! \n"); } class CUnit:public ITimer { public: CUnit(); ~CUnit(); virtual bool DoAction(); }; //--------------------------------- bool CUnit::DoAction() { fprintf(stdout," CUnit:: Hello Word!!! \n"); }
И так далее...
В результате, после создания и включения таймера для объектов, например, типа CAbonent, обработчик сигнала сразу, без всякого анализа вызовет нужную функцию DoAction().
Комментарии