As the title says, I'm looking for the best way to implement multiple timers in C++ (not c++ 11).
My idea is having a single pthread (posix) to handle timers.
I need at least 4 timers, 3 periodic and 1 single shot.
The minimum resolution should be 1 second (for the shortest timer) and 15 hours for the longest one.
All the timers should be running at the same time.
These are the different implementations that come to my mind (I don't know if they are the safest in a thread environment or the easiest ones):
1) Using itimerspec, sigaction and sigevent structure like this:
static int Tcreate( char *name, timer_t *timerID, int expireMS, int intervalMS )
{
struct sigevent te;
struct itimerspec its;
struct sigaction sa;
int sigNo = SIGRTMIN;
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = app;
sigemptyset(&sa.sa_mask);
if (sigaction(sigNo, &sa, NULL) == -1)
{
perror("sigaction");
}
/* Set and enable alarm */
te.sigev_notify = SIGEV_SIGNAL;
te.sigev_signo = sigNo;
te.sigev_value.sival_ptr = timerID;
timer_create(CLOCK_REALTIME, &te, timerID);
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = intervalMS * 1000000;
its.it_value.tv_sec = 0;
its.it_value.tv_nsec = expireMS * 1000000;
timer_settime(*timerID, 0, &its, NULL);
return 1;
}
2) Using clock() and checking for time difference, like this:
std::clock_t start;
double duration;
start = std::clock();
duration = ( std::clock() - start ) / (double) CLOCKS_PER_SEC;
3) Using chrono like this:
auto diff = tp - chrono::system_clock::time_point();
cout << "diff:" << chrono::duration_cast<chrono::minutes>(diff).count()
<< " minute(s)" << endl;
Days days = chrono::duration_cast<Days>(diff);
cout << "diff:" << days.count() << " day(s)" << endl;
Please, consider these as ideas, not actual working code.
What is your opinion about it ?
If your timer thread is responsible only for the timers, and the minimum resolution is 1 second, and the timing doesn't need to be that precise (i.e. if +/- 0.1 second is good enough), then a simple implementation for the timer thread is to just sleep for 1 second, check for any timers that need to fire, and repeat, as in the following psuedocode:
repeat:
sleep 1
t = t+1
for timer in timers where timer(t) = true:
fire(timer)
The hard part will be populating the structure that stores the timers - presumably timers will be set by other threads, possibly by multiple threads that could try to set timers simultaneously. It would be advisable to use some standard data structure like a thread-safe queue to pass messages to the timer thread, which on each cycle would then update the collection of timers itself:
repeat:
sleep 1
t = t+1
while new_timer_spec = pop(timer_queue):
add_timer(new_timer_spec)
for timer in timers where timer(t) = true:
fire(timer)
Another thing to consider is the nature of fire(timer) - what to do here really depends on the needs of the threads that use the timers. Perhaps just setting a variable that they could read would be sufficient, or maybe this could fire a signal that threads could listen for.
Since all your timer creation apparently goes through a single API (i.e., the controlling code has visibility into all timers), you can avoid signals or busy-looping entirely and keep a sorted list of timers (like a std::map keyed by deadline), and simply wait on a condition variable using (for example) pthread_cond_timedwait. The condition variable mutex protects the list of timers.
If you schedule a new timer whose deadline is earlier than the current "next" timer, you'll need to wake the sleeping thread and schedule an adjusted sleep (if it wasn't for this requirement you could use plain usleep or whatever). This all happens inside the mutex associated with the condition variable.
You don't have to use condition variables, but they seem the cleanest, since the associated mutex is naturally used to protect the list of timers. You could probably also build this on top of a semaphone with sem_timedwait, but or on top of select on an internal socket, pipe or something like that, but then you're stuck separately controlling multi-threaded access to the timer queue.
Related
I am trying to implement a background user-space program that will perform various tasks and calculations every 100ms in Linux. I can do this by using the alarm signal in Linux and the following structure is the way I implemented my interval timer.
void timer_handler (int signum){
printf("In timer handler!\n");
}
int main (){
struct sigaction s_action;
struct itimerval timer;
/* Set Up a Timer */
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&s_action, 0, sizeof (s_action));
s_action.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &s_action, NULL);
/* Timer configuration for 100ms */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 100000;
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 100000;
/* Set up the timer */
setitimer (ITIMER_VIRTUAL, &timer, NULL);
while(1);
}
This approach, however, does not seem to be the optimal way of doing (in terms of performance) this because of the infinite loop. It significantly increases CPU utilization. Once it starts running in the background, the performance of my other programs degrades by as mush as 15%.
What I would ideally want is to have a program that, unless a timer interrupt occurs, will keep sleeping. Multi-threading seems to be an option but I am not very experienced with that subject. I would appreciate any suggestions or pointers on how to implement such program with minimal overhead.
Read time(7), signal(7), timerfd_create(2), poll(2), nanosleep(2) and Advanced Linux Programming.
Your signal handler is incorrect (it should not call printf; it could write).
You could have
while(1) poll(NULL, 0, 1);
but probably a real event loop using poll on a file descriptor initialized with timerfd_create should be better.
I assume of course that you are fairly confident that every periodic task lasts much less than the period. (e.g. that each task needs no more than 50 milliseconds but has a 100 millisecond period).
I would like to schedule an event in a specific time, more precisely, I want to generate a poisson traffic. So I need to send a packet at specific time intervals that are generated from an exponential distribution. I have done some researches on the Internet and found that the setitimer method can schedule an alarm signal after a certain time, but I don't know how to use it in my case.
Thanks for the advice. I followed what you have said. I still have a little query: in my code I need to schedule two independant events at the same time, typically, filling two queues simultaneously. This is what I did right now:
void Queue_class::SetPoissonTraficFirstQueue(void)
{ // add one packet to the queue
struct sigaction act ;
struct itimerval timer ;
act.sa_handler = this ;
sigempty_set(&act.sa_mask) ; // no signal is added to the sa_mask
act.sa_flags = 0 ;
sigaction(SIGALARM, &act,0) ;
timer.it_value.tv_usec = 0 ;
timer.it_value.tv_sec = exponential_variable() ; // generates a random exponential variable
timer.it_interval.tv_sec = 0 ;
timer.it_interval.tv_usec = 0 ;
setitimer(ITIMER_REAL, *timer, NULL) ;
}
And the same function for the other queue but with a different exponential random variable
In the main, I do what follows:
int main()
{
Queue_class queue ;
queue.SetPoissonTraficFirstQueue() ;
queue.SetPoissonTraficSecondQueue() ;
// do business
}
I have two question please:
1- Is it a good solution to call the function internally with the pointer "this" in sa_handler method?
2- In the main function, do the two processes occur simultaneously as I want: I mean are both queues filled at the same time?
Lets say you want to schedule a timer for 6PM today, you get a time_t of that time (using e.g. strptime or other functions), then you can use difftime to get the number of seconds between now and then. This value can be used for the "value" of the timer (i.e. itimerval.it_value.tv_sec). If the interval is cleared, then this will be a one-off timer.
On the other hand, if you want to create a recurring timer, that is called every X second, then set both the value and interval to X.
In both these vases, use ITIMER_REAL, and have a signal handler catch SIGALRM.
I use ALSA in async mode with callbacks (snd_async_add_pcm_handler()). Every ALSA's callback is called from SIGIO signal handler. Every callback calls my function getCurrentTimeMs():
// Return current milliseconds (don't care - local time or UTC).
long long getCurrentTimeMs(void)
{
std::cout << "+"; std::cout.flush();
long long ret = 0;
#define Z
#ifdef Z
struct timespec ts;
clock_gettime( CLOCK_MONOTONIC, &ts);
ret = ts.tv_sec * 1000;
ret += ts.tv_nsec / 1000000;
#else
boost::posix_time::ptime now = boost::posix_time::microsec_clock::local_time();
std::cout << "."; std::cout.flush();
boost::posix_time::ptime epoch_start(boost::gregorian::date(1970,1,1));
std::cout << "."; std::cout.flush();
boost::posix_time::time_duration dur = now - epoch_start;
std::cout << "."; std::cout.flush();
ret = dur.total_milliseconds();
#endif
std::cout << "-"; std::cout.flush();
return ret;
}
Signal handler can be called before previous handler is finished;
i need current time in ms to measure precise samplerate.
If i comment #define Z, the boost is used. In "boost mode" application hangs after unpredictable amount of time from audio playing start. strace show application hangs on this:
write(1, "+"..., 1) = 1
gettimeofday({1332627252, 660534}, NULL) = 0
futex(0xb68dba4c, FUTEX_WAIT_PRIVATE, 2, NULL <unfinished ...>
But 0xb68dba4c occured only 2...3 times in all the trace log. The futex(0xb68dba4c ... is not the thing that occurs on every getCurrentTimeMs() call. But when it occurs, everything hangs and it occurs only after that gettimeofday; i see "+." on the console and then that futex occurs. But before that, application can play tons of sound, calling getCurrentTimeMs() on each callback 50 times per second. Such a mystery...
With #define Z my code is used. In this case the application works great - playing gigabytes of WAV files with no hangs.
The application has 2 threads running via boost::threadpool and both using the getCurrentTimeMs(); lets assume i have some deadlock errors; but i have no idea how #define Z may affect that.
EDIT:
My question is answered in this way and i accept this answer:
1) http://permalink.gmane.org/gmane.linux.alsa.devel/96282
2) http://answerpot.com/showthread.php?3448138-ALSA+async+callback+re-enter+and+DEADLOCK.
If this is what it looks like to me, there are two kinds of asynchronous scheduling to consider: asynchronous threads, and asynchronous interrupts ("signals"). Threads run independent of each other unless they explicitly synchronize; signals are scheduled asynchronously but preempt and block whatever thread they're delivered to. It looks very much like the boost functions or iostreams you're calling achieve thread-safety by locking, which makes them _un_safe to call in an interrupt handler because the thread the handler preempted may very well already hold the lock.
One thing you might do is to arrange to have all signals delivered to a thread that does nothing else -- maybe fire up a thread immediately on startup and have your mainline code run there, leaving the original main thread dedicated to signal handling.
On behalf, sorry for my far from perfect English.
I've recently wrote my self a demon for Linux (to be exact OpenWRT router) in C++ and i came to problem.
Well there are few threads there, one for each opened TCP connection, main thread waiting for new TCP connections and, as I call it, commander thread to check for status.
Every thing works fine, but my CPU is always at 100%. I now that its because of the commander code:
void *CommanderThread(void* arg)
{
Commander* commander = (Commander*)arg;
pthread_detach(pthread_self());
clock_t endwait;
while(true)
{
uint8_t temp;
endwait = clock () + (int)(1 * CLOCKS_PER_SEC);
for(int i=0;i<commander->GetCount();i++)
{
ptrRelayBoard rb = commander->GetBoard(i);
if (rb!= NULL)
rb->Get(0x01,&temp);
}
while (clock() < endwait);
}
return NULL;
}
As you can see the program do stuff every 1s. Time is not critical here. I know that CPU is always checking did the time passed. I've tried do do something like this:
while (clock() < endwait)
usleep(200);
But when the function usleep (and sleep also) seam to freeze the clock increment (its always a constant value after the usleep).
Is there any solution, ready functions (like phread_sleep(20ms)), or walk around for my problem? Maybe i should access the main clock somehow?
Here its not so critical i can pretty much check how long did the execution of status checking took (latch the clock() before, compare with after), and count the value to put as an argument to the usleep function. But in other thread, I would like to use this form.
Do usleep is putting whole process to freeze?
I'm currently debugging it on Cygwin, but don't think the problem lies here.
Thanks for any answers and suggestions its much appreciated.
J.L.
If it doesn't need to be exactly 1s, then just usleep a second. usleep and sleep put the current thread into an efficient wait state that is at least the amount of time you requested (and then it becomes eligible for being scheduled again).
If you aren't trying to get near exact time there's no need to check clock().
I've I have resolved it other way.
#include <sys/time.h>
#define CLOCK_US_IN_SECOND 1000000
static long myclock()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * CLOCK_US_IN_SECOND) + tv.tv_usec;
}
void *MainThread(void* arg)
{
Commander* commander = (Commander*)arg;
pthread_detach(pthread_self());
long endwait;
while(true)
{
uint8_t temp;
endwait = myclock() + (int)(1 * CLOCK_US_IN_SECOND);
for(int i=0;i<commander->GetCount();i++)
{
ptrRelayBoard rb = commander->GetBoard(i);
if (rb!= NULL)
rb->Get(0x01,&temp);
}
while (myclock() < endwait)
usleep((int)0.05*CLOCK_US_IN_SECOND);
}
return NULL;
}
Bare in mind, that this code is vulnerable for time change during execution. Don't have idea how to omit that, but in my case its not really important.
What is the simplest way to wait for more objects than MAXIMUM_WAIT_OBJECTS?
MSDN lists this:
Create a thread to wait on MAXIMUM_WAIT_OBJECTS handles, then wait on that thread plus the other handles. Use this technique to break the handles into groups of MAXIMUM_WAIT_OBJECTS.
Call RegisterWaitForSingleObject to wait on each handle. A wait thread from the thread pool waits on MAXIMUM_WAIT_OBJECTS registered objects and assigns a worker thread after the object is signaled or the time-out interval expires.
But neither are them are very clear. The situation would be waiting for an array of over a thousand handles to threads.
If you find yourself waiting on tons of objects you might want to look into IO Completion Ports instead. For large numbers of parallel operations IOCP is much more efficient.
And the name IOCP is misleading, you can easily use IOCP for your own synchronization structures as well.
I encountered this limitation in WaitForMultipleObjects myself and came to the conclusion I had three alternatives:
OPTION 1. Change the code to create separate threads to invoke WaitForMultipleObjects in batches less than MAXIMUM_WAIT_OBJECTS. I decided against this option, because if there are already 64+ threads fighting for the same resource, I wanted to avoid creating yet more threads if possible.
OPTION 2. Re-implement the code using a different technique (IOCP, for example). I decided against this too because the codebase I am working on is tried, tested and stable. Also, I have better things to do!
OPTION 3. Implement a function that splits the objects into batches less than MAXIMUM_WAIT_OBJECTS, and call WaitForMultipleObjects repeatedly in the same thread.
So, having chosen option 3 - here is the code I ended up implementing ...
class CtntThread
{
public:
static DWORD WaitForMultipleObjects( DWORD, const HANDLE*, DWORD millisecs );
};
DWORD CtntThread::WaitForMultipleObjects( DWORD count, const HANDLE *pHandles, DWORD millisecs )
{
DWORD retval = WAIT_TIMEOUT;
// Check if objects need to be split up. In theory, the maximum is
// MAXIMUM_WAIT_OBJECTS, but I found this code performs slightly faster
// if the object are broken down in batches smaller than this.
if ( count > 25 )
{
// loop continuously if infinite timeout specified
do
{
// divide the batch of handles in two halves ...
DWORD split = count / 2;
DWORD wait = ( millisecs == INFINITE ? 2000 : millisecs ) / 2;
int random = rand( );
// ... and recurse down both branches in pseudo random order
for ( short branch = 0; branch < 2 && retval == WAIT_TIMEOUT; branch++ )
{
if ( random%2 == branch )
{
// recurse the lower half
retval = CtntThread::WaitForMultipleObjects( split, pHandles, wait );
}
else
{
// recurse the upper half
retval = CtntThread::WaitForMultipleObjects( count-split, pHandles+split, wait );
if ( retval >= WAIT_OBJECT_0 && retval < WAIT_OBJECT_0+split ) retval += split;
}
}
}
while ( millisecs == INFINITE && retval == WAIT_TIMEOUT );
}
else
{
// call the native win32 interface
retval = ::WaitForMultipleObjects( count, pHandles, FALSE, millisecs );
}
// done
return ( retval );
}
Have a look here.
If you need to wait on more than MAXIMUM_WAIT_OBJECTS handles, you can either create a separate thread to wait on MAXIMUM_WAIT_OBJECTS and then do a wait on these threads to finish. Using this method you can create MAXIMUM_WAIT_OBJECTS threads each of those can wait for MAXIMUM_WAIT_OBJECTS object handles.