Мне нужно реализовать таймер с функцией обработчика времени ожидания в С++. Для этого я создаю таймер и инициализирую sigev_notify_function для sigevent одной из функций-членов класса. Ниже приведен код.
timer.hpp
#ifndef TIMERHELPER_H_
#define TIMERHELPER_H_
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <iostream>
using namespace std;
#define CLOCKID CLOCK_REALTIME
#define SIG SIGUSR1
typedef void (*TimerHandler)(sigval_t signum);
class TimerTimeoutHandler
{
public:
virtual void handlerFunction( void ) = 0;
};
class Timer
{
public:
Timer( TimerTimeoutHandler * timeHandler );
~Timer();
void setDuration(long int seconds);
void start();
void restart();
void timeout();
void stop();
private:
void createTimer(timer_t *timerid, TimerHandler handler_cb);
void startTimer(timer_t timerid, int startTimeout, int cyclicTimeout);
void stopTimer(timer_t timerid);
void timeOutHandler( sigval_t /* signum */ );
long int m_Duration;
TimerTimeoutHandler * timeOutHandlerImp;
timer_t timerid;
};
class TimeTimeoutHandlerImp : public TimerTimeoutHandler
{
public:
TimeTimeoutHandlerImp(){}
~TimeTimeoutHandlerImp(){}
void handlerFunction( void );
};
#endif /* TIMERHELPER_H_ */
timer.cpp
#include "timer.hpp"
Timer::Timer( TimerTimeoutHandler * timeHandler )
{
timeOutHandlerImp = timeHandler;
m_Duration = 0;
createTimer( &timerid, timeOutHandler );
}
Timer::~Timer()
{
stopTimer( timerid );
}
void Timer::setDuration(long int seconds)
{
m_Duration = seconds;
}
void Timer::start()
{
startTimer(timerid, m_Duration, 3);
}
void Timer::restart()
{
stopTimer(timerid);
startTimer(timerid, m_Duration, 0);
}
void Timer::stop()
{
stopTimer(timerid);
}
void Timer::createTimer(timer_t *timerid, TimerHandler handler_cb)
{
sigevent sev;
pthread_attr_t attr;
pthread_attr_init( &attr );
sched_param parm;
parm.sched_priority = 255;
pthread_attr_setschedparam(&attr, &parm);
sev.sigev_notify_attributes = &attr;
sev.sigev_notify = SIGEV_THREAD;
sev.sigev_notify_function = handler_cb;
sev.sigev_signo = SIG;
sev.sigev_value.sival_ptr = timerid;
timer_create(CLOCKID, &sev, timerid);
}
void Timer::startTimer(timer_t timerid, int startTimeout, int cyclicTimeout)
{
itimerspec its;
/* Start the timer */
its.it_value.tv_sec = startTimeout;
its.it_value.tv_nsec = 0;
/* for cyclic timer */
its.it_interval.tv_sec = cyclicTimeout;
its.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &its, NULL);
}
void Timer::stopTimer(timer_t timerid)
{
itimerspec its;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = 0;
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
timer_settime(timerid, 0, &its, NULL);
}
void Timer::timeOutHandler( sigval_t /* signum */ )
{
timeOutHandlerImp->handlerFunction();
}
void TimeTimeoutHandlerImp::handlerFunction( void )
{
cout << "time handler invoked" << endl;
}
Но во время компиляции я столкнулся с проблемой (это может быть проблема дизайна)
g++ timer.cpp
timer.cpp: In constructor ‘Timer::Timer(TimerTimeoutHandler*)’:
timer.cpp:8:43: error: no matching function for call to ‘Timer::createTimer(void**, <unresolved overloaded function type>)’
timer.cpp:8:43: note: candidate is:
In file included from timer.cpp:1:0:
timer.hpp:35:14: note: void Timer::createTimer(void**, TimerHandler)
timer.hpp:35:14: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘TimerHandler {aka void (*)(sigval)}’
Достаточно ли хороша эта конструкция, чтобы разделить реализацию таймера и реализацию обработчика тайм-аута? Я использую разные файлы .hpp и .cpp для всех определений и объявлений классов. Но для простоты я вставил весь код в два файла для лучшего понимания здесь.
Пожалуйста, посоветуйте хороший дизайн для реализации таймера. Класс таймера не должен зависеть от класса обработчика времени ожидания. В основном таймер UNIX должен вызывать функцию класса обработчика тайм-аута сразу после истечения срока действия таймера. Пожалуйста, предложите.
TimerTimeoutHandler
) посмотритеstd::function
вместо это как класс, который должен быть унаследован. См. этот мой старый ответ для получения некоторой информации о том, как использоватьstd::function
. - person Some programmer dude   schedule 26.09.2013std::thread
, и его можно использовать на любой платформе, которая имеет компилятор C++11. - person Some programmer dude   schedule 26.09.2013