flammi88
flammi88

Reputation: 401

Execute a function periodically every 10ms on linux

I am currently working on a program that must do some work regularly. At the moment I using the following construction:

int main(int argn, char** argv) {
    for(;;) {
        //Do work - the programm spends 5-8ms here

        nanosleep(...); //Sleep 10ms
    }
    return 0;
}

The problem is: One loop execution should always last 10ms. Because of the high amount of time spend in the working part of the loop I can't sleep simply sleep for 10ms...

A solution might be measuring the time spend on work with clock_gettime() and adjust the nanosleep() accordingly. But I am not happy with this solution, because it's very easy to place code outside the area that's measured...

I have searched the internet for alternatives, I found the three calls:

It's okay if the solution is not portable to Windows or other operating systems.

But I am not sure which solutions fits best to my problem. Any advice or suggestions? What are the pros and cons with the 4 alternatives I mentioned?

EDIT: There is also another problem with this solution: If i get the documentation right, the nanosleep syscall put the process into sleep for at least 10ms, but it can take longer if the system is under load... Is there any way to optimize that?

EDIT2: For your information: In the do work part a network request is made to a another device on the network (a microcontroller or a PLC that is able to answer the request in time). The result is being processed and send back to the device. I know Linux is not a realtime OS and not optimal for this kind of task... It's no problem if the solution is not perfect realtime, but it would be nice to get as much realtime as possible.

Upvotes: 3

Views: 2136

Answers (3)

Sagar Gandhi
Sagar Gandhi

Reputation: 965

Signal Handling is the most preferred way to do it .I prefer timer_create as it is posix function conforming to POSIX.1-2001. Microsoft also provides help for writing POSIX Standard Code.

Upvotes: 1

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215547

Use clock_nanosleep which lets you request to sleep until a given absolute time (TIMER_ABSTIME flag) rather than taking a duration. Then you can simply increment the destination absolute time by 10ms on every iteration.

Using clock_nanosleep also allows you (if you want) to use the monotonic clock option and avoid having to deal with the possibility of the user/admin resetting the system clock while your program is running.

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182847

Check the time right before the call to nanosleep and compute how long to sleep right there. There will be no need to measure any code. Just note the time you return from nanosleep and calculate how much more time you need to sleep.

Upvotes: 1

Related Questions