LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   c timer in linux ubuntu (https://www.linuxquestions.org/questions/programming-9/c-timer-in-linux-ubuntu-4175715729/)

lnx8a 08-15-2022 11:04 PM

c timer in linux ubuntu
 
i am new to linux programming in C. Was looking for a periodic timer that repeats very fast like each 10 msec with overlap calling protection. Is the posix timer reliable to run on linux versus the linux specific timers?.

pan64 08-16-2022 12:51 AM

Hi, and welcome here, at LQ!

without context hard to say anything. Why do you think the posix timer is not reliable?

NevemTeve 08-16-2022 04:02 AM

Mind you,Linux is not a Real-Time system i.e. there are no guarranted time-limits or intervals.

EdGr 08-16-2022 05:43 AM

You seem to be referring to nanosleep.

I would not rely on time delays much below 100ms. A desktop OS is not built to do that. It runs too many processes.

You need to design your program so that it can tolerate timing errors of hundreds of milliseconds. Or, you need to use an OS intended for real-time.
Ed

GazL 08-16-2022 07:06 AM

A while back, for fun, I wrote a simple animation program that ran on the linux console (writing directly to the VCS deviceš). I used a clock_nanosleep() to govern the display loop, adjusting the sleep duration each time to compensate for drift˛. Typically the latency on the wake was sub 1msec. Setting scheduling class and priority might help with reliability, but as Nev' points out, Linux is not a true RTOS and there are no guarantees.

I'd expect the results using a timer and SIGALRM to be similar.

___
1) I eventually shelved the project as the VCS device doesn't support mmap and writing out a full frame each time using write(2) was just too inefficient/slow.

2) using TIMER_ABSTIME on the nanosleep is also a good way to avoid latency induced drift.

sundialsvcs 08-18-2022 04:31 PM

Here's the best way to consider "timers." A timer that is set to go off every 10 msec will ensure that your process will wake up at least that often. But, having woken up, your process then needs to "look at the clock to find out what time it is." It should process its entire time-ordered work list, re-checking the clock every time, until it either runs out of work to do or finds that the next unit of work is due "more than 10 msec from now." At which time it can yield, knowing that the next timer-pop will happen "soon."

It is entirely possible that the timer might go off again while the process is doing its work, so it's entirely possible that it might "wait for the next alarm" and actually wind up "not waiting at all." The timer simply serves as a mechanism to allow the process to avoid monopolizing system resources ("busy waiting ...") when it has nothing to do. The process must constantly refer to the immediate time-of-day value as it processes its to-do list. The unit-of-work might be processed slightly later than the specified time – since "Linux is not an RTOS" – but it will not be processed sooner.

bigearsbilly 09-07-2022 07:44 AM

Here is one way to do it:

Code:

#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>


void doit(int n)
{
        time_t tp = time(0);
        printf("%s\r\n\r\n", ctime(&tp));
}

int main(int args, char **arv)
{
        const struct sigaction sa = { doit, 0, 0 };
        sigaction(SIGALRM, &sa, 0);

        while(1){
                alarm(1);
                sleep(10);
        }
}


bigearsbilly 09-07-2022 07:58 AM

more flexible

I just knocked this up quick it just echos what you type with the timer being annoying


Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include <signal.h>
#include <time.h>


static char * chomp(char * line)
{
        char *p = line;
        strsep( &p, "\r\n");
        return p;
}


void squawk(union sigval unused)
{
        static int n;
        fprintf(stderr, "\nhello %d\n", ++n);
        return;
}

int start_ticker()
{
        timer_t timid ;
        // union sigval sv = {0,};
        struct sigevent sev = { 0, };
        sev.sigev_notify = SIGEV_THREAD;
        sev.sigev_notify_function = squawk;

        if (timer_create( CLOCK_REALTIME,  &sev, &timid) == 0) {

                // struct timespec tick = { 1, 0 };
                struct itimerspec ticks = { { 2, 0}, {2, 0} };
                timer_settime( timid, 0, &ticks, NULL);
        }  else {
                perror("timer_create");
                return 0;
        }
        return 1;
}


sundialsvcs 09-12-2022 12:28 PM

Always remember that: in a "non-real time OS," such as Linux, the occurrence of a timer interrupt only causes the affected process(es) to "become runnable." It does not cause the OS to "move Hell and High Water To ..." cause said process to "immediately run." (i.e. with to strive to fulfill some promised maximum contractual degree of "latency," of which Linux by its design has none.)

And this, of course, is the fundamental difference between "real-time" and "non-real-time" OSes . . .

A "non-real-time" OS promises that "you will not wake up sooner." But it does not promise that "you will not wake up later," nor that you might not occasionally "wake up twice, finding nothing to do the second time."


All times are GMT -5. The time now is 09:58 PM.