views:

91

answers:

3

I'm using the GCC compiler and C++ and I want to make a timer that triggers an interruption when the countdown is 0.

Any Ideas? Thanks in advance.

EDIT

Thanks to Adam, I know how to do it.

Now. What about multiple timers running in parallel?

Actually, these timers are for something very basic. In NCURSES, I have a list of things. When I press a key, one of the things will change colors for 5 seconds. If I press another key, another thing in the list will do the same. It's like emphasize strings depending on the user input. Is there a simpler way to do that?

+1  A: 

One way to do it is to use the alarm(2) system call to send a SIGALRM to your process when the timer runs out:

void sigalrm_handler(int sig)
{
    // This gets called when the timer runs out.  Try not to do too much here;
    // the recommended practice is to set a flag (of type sig_atomic_t), and have
    // code elsewhere check that flag (e.g. in the main loop of your program)
}

...

signal(SIGALRM, &sigalrm_handler);  // set a signal handler
alarm(10);  // set an alarm for 10 seconds from now

Take careful note of the cautions in the man page of alarm:

alarm() and setitimer() share the same timer; calls to one will interfere with use of the other.

sleep() may be implemented using SIGALRM; mixing calls to alarm() and sleep() is a bad idea.

Scheduling delays can, as ever, cause the execution of the process to be delayed by an arbitrary amount of time.

Adam Rosenfield
Great, this is exactly what I needed. Thanks!
Tomas
A: 

An easy, portable way to implement an interrupt timer is using Boost.ASIO. Specifically, the boost::asio::deadline_timer class allows you to specify a time duration and an interrupt handler which will be executed asynchronously when the timer runs out.

See here for a quick tutorial and demonstration.

Charles Salvia
A: 

Here is a way to solve this problem doing well on both time and space ('complexity') and never using more than one 'timer event' from the operating system services.

(1) Terminology

Let's start being somewhat clear on terminology and then try to be more clear by giving some hypothetical examples:

So, in our work, as time goes on, we discover (receive) 'events'; we receive these events at possibly some thousands or more per second; each event has a 'time', that is, 'clock on the wall' time, usually in the future, when the event should cause an 'action' (raise, trigger, generate an interrupt, message, condition, etc.). For the event that has the earliest time, we want to cause the action at the time of that event or as soon as we can after that time.

So, by analogy, our problem is like a TO DO list:


event = video conference with CA

time = 9:15 AM

action = start video software


event = take shower

time = 7:00 AM

action = wake SO


event = wake up

time = 6:45 AM

action = play Anvil Chorus


(2) First Grade Solution

Pick a positive integer n, say, 1024.

Go to the classic algorithm 'heap sort' and allocate and define a heap in array x(1), x(2), ..., x(n). Each component of this array can be used to store the data for some one event.

Let integer m be the number of events in the heap now. Start with m = 0. We will always have m <= n. In case after allocating our array of n components we discover that we have more events to store than n, we modify this first grade solution to the second grade solution below.

In a heap, the components need to have an 'ordering' based on a 'key'. In our heap, the keys are the clock on the wall times of the events.

To review, for positive integer i = 1, 2, ..., m, for array component x(i), let k(x(i)) be the value of that component's key. Then the (ascending) 'heap condition' is, for i = 2, 3, ..., m, and letting i/2 be the integer part of this quotient,

k(x(i/2)) < k(x(i))

So a heap is not really 'sorted' but is a clever and 'implicit' way to store a 2-way branched tree.

There are two 'heap operations', a faster one and a slower one, used to establish the heap condition. The faster operation takes a heap of m < n components and a new event, puts the event in component x(m + 1), considers the heap condition for i = m + 1 and exchanges if necessary, etc., and finally sets m = m + 1. The slower operation has a heap of m components, for some i = 1, 2, ..., m - 1, removes the event in component x(i), and works to put an event in x(i) and establish a heap of m - 1 components. For the details, see a text on algorithms and data structures, e.g., Knuth's 'The Art of Computer Programming: Sorting and Searching' or just work out the details as an exercise.

We want our heap to be in 'ascending' order on time, that is, so that x(1) has the event with the earliest time (as is common and convenient, we assume that our computer clock has enough 'resolution' that each event time can be unique; as below, having each time unique eases removing events before their actions have been taken in case we want to do that).

Suppose we receive an event:

If the time of this event is earlier than the current time, then we just cause the action of that event. Yes, for some applications we might want to modify this step if we anticipate some cases of events arriving faster than we can take the actions; I discuss this point below.

Else we put the event in component m + 1 of the array and perform (the faster) one of the two classic heap operations to establish the heap condition again.

If now m = 1, then we ask operating system services for an interrupt at the time of the event in array component x(1).

If m > 1 and establishing the heap condition again changed the time of the event in array component x(1), then we cancel the operating system services interrupt and ask for an interrupt at the time for the event now in x(1).

When we get an interrupt, we take the action of the event in array component x(1) and set m = m - 1. Now array component x(1) has no event and is 'empty'. So, we need to correct the 'empty' component x(1) and, in particular, to establish the heap condition again. To this end, if m > 0, then we use (the slower) one of the two heap operations and, then, ask operating system services for an interrupt at the time of the event now in array component x(1).

We can support canceling an event: Given the time (again, each time is unique) of the event, using the fact that the heap really stores a binary tree, find the event in the heap, remove it, and establish the heap condition again.

(3) Related Application

Suppose we receive 2 billion numbers one at a time and at the end want to have the 20 smallest. Or, if we want the 20 largest, then we use an ascending heap.

(4) Second Grade Solution

If we discover that n is too small, then we regard the heap above as a 'leaf'. Then for some positive integer k, we build a k-way balanced tree where the leafs are n component heaps as above and the nodes are k-component heaps that point to nodes or leafs in the tree farther from the root of the tree.

When we need more nodes or leafs in the tree, we allocate storage. As usual, we may select a positive integer p and actually never free node heaps to fewer than p, and select positive integer q and actually never free leaf storage to fewer than q. In this way we can 'smooth out' the number of storage allocation or free requests to our dynamic storage allocation manager.

Yes, here we might do some optimization math starting with costs of storage allocation and freeing and some assumptions about the 'stochastic arrival process' of the events. Due to the famous renewal theorem in stochastic point processes, we might assume that the arrival process is just a non-stationary Poisson process with slowly varying arrival rate.

(5) Detail of Getting Too Busy

It may be that at times events arrive faster than we can take their actions. So, at 10:02 AM we may have 8,022 events that have arrived but for which we have taken no action and with all the times of the events earlier than time 10:02 AM. Now what? Well we might still like to execute the events in ascending order on time. So, we can go ahead and put the events into the heap and/or balanced tree storage until are 'caught up' and then take the actions in ascending order on time.

(6) Problem: How to modify for many cores?

a_programmer