Reputation: 123
This is a sample program that I have created to illustrate a problem. It is intended that the program should print (count) the time in seconds since program start (or counter reset) every second and print a string every 10 seconds. Every 90 seconds, a different string should be written to stdout. But this does not work quite as intended, and I'm not sure why.
#include <iostream> // time_t time();
#include <stdio.h> // printf();
#include <time.h>
#include <unistd.h> // sleep();
int main(void) {
time_t task1_time = (time(NULL) + 10); // Saves the time 10 seconds ahead from now!
time_t task2_time = (time(NULL) + 90); // Saves the time 90 seconds ahead from now!
int seconds = 0; // Variable to count seconds.
while (1) {
if (time(NULL) >= task1_time) { // If the time now has caught up with the 10 seconds:
task1_time = (time(NULL) + 10); // Saves the time additional 10 seconds ahead from now!
printf("Task 1 executing!\n"); // Prints a string to stdout.
seconds = 0; // Resets the secondcounter.
}
else {
if (time(NULL) >= task2_time) { // If the time now has caught up with the 90 seconds:
task2_time = (time(NULL) + 90); // Saves the time additional 90 seconds ahead from now!
printf("\nTask 2 executing!\n"); // Prints a string to stdout.
}
}
printf("%d ", seconds); // Prints to stdout the number of seconds that have been counted.
seconds = seconds + 1; // Adds 1 to seconds.
sleep(1); // Wait 1 second.
}
return 0;
}
What happens is that the program runs for 10 seconds without printing. Then, all the following phrase is printed to stdout at once:
"0 1 2 3 4 5 6 7 8 9 Task 1 executing!"
Thereafter nothing happens for another 10 seconds, until the same phrase is reprinted. And so it goes. After about 90 seconds, the following phrase is printed:
"Task 2 executing!"
The strings printed to stdout is supposed to represent more realistic tasks to be performed in a real application. My purpose is to "interrupt" the program every 10th and 90th seconds to perform separate tasks, while the program in general can keep on with other things in between. I have achieved this before with mbed micro-controllers, where so-called "Tickers" executes such interruptions, but I have not been able to find a Ticker feature available in standard C or C++.
I have also tried another approach by exchanging sleep(1) with wait(1), and added this prototype to the code:
void wait (int seconds)
{
clock_t end_wait = (clock() + (seconds * CLOCKS_PER_SEC));
while (clock() < end_wait) {}
}
The program behaviour was the same.
I have also studied the answers given at the post Print message every x seconds [duplicate], but it seems to me that these solutions makes the program unable to do anything else than waiting between the intervals.
A couple of questions:
Q1: Why isn't one integer printed to stdout each second instead of all integers from 10 seconds back in time being printed at the same time?
Q2: Will this approach waste unnecessary CPU-power while waiting/sleeping?
And of course:
All proposed solutions and code examples will be appreciated.
Additional information: Intended operating system: Linux
Upvotes: 1
Views: 2518
Reputation: 806
Well, in Linux user space you can't set up an interrupt as you used to do with your microcontroller with Tickers, because each architecture where Linux runs can be different and handle interrupts in a different way.
You could run a separate thread though, you can use POSIX threads, find a tutorial here: http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html
Upvotes: 0
Reputation: 3045
Q1: Why isn't one integer printed to stdout each second instead of all integers from 10 seconds back in time being printed at the same time?
The function printf
uses buffered output. A fflush(stdout)
would fix this.
Q2: Will this approach waste unnecessary CPU-power while waiting/sleeping?
Well not the function sleep
. But the function wait
that you use would take up CPU cycles while waiting.
If you want to execute some tasks every n
seconds, you can go for threads
or timers
Upvotes: 1
Reputation: 182649
Q1: Why isn't one integer printed to stdout each second instead of all integers from 10 seconds back in time being printed at the same time?
Because output is buffered. You need to flush it in some way, perhaps using fflush(stdout)
right after the printf
.
I am not sure what you are trying to achieve but you could easily get something like a "tick interrupt" using signals. You have to be careful what functions you call from signals though, they have to be "async-signal-safe".
For example on Linux, which you mentioned you could use timer_create
and you will get a signal for every "tick" you specify.
Upvotes: 2
Reputation: 409196
The statement
printf("%d ", seconds);
really prints the time, but it doesn't flush it to the output terminal. Add a call to fflush
directly afterwards.
Upvotes: 6