5

I'm looking for a way to do timing events in C/C++ under Linux.
E.g. execute a piece of code every 100 milliseconds. (No more, no less, soft real-time)

The only options I've seen till now are:

  • Looping infinitely, and check every time if it is time to execute.
  • Sleeping the thread until it is time to run.

Infinitely checking if it is time to run, has the disadvantage that it is (too) CPU intensive.
Sleeping until it is time, has the disadvantage that it is not precise. The sleep-time is just a guideline, it could sleep way more.

Now I was wondering if any of you know how to do real-time timing events in C/C++ under Linux.

Kara
  • 6,115
  • 16
  • 50
  • 57
Dennis
  • 323
  • 7
  • 17
  • 1
    How real-time do you need to be? Linux isn't really an RTOS. – Carl Norum Feb 28 '13 at 19:02
  • Yes, is a RTOS assigment. Take a look on QP framework. – Mihai8 Feb 28 '13 at 19:05
  • sleep is precise enough, if you know how to use it – Zaffy Feb 28 '13 at 19:06
  • Did you see http://stackoverflow.com/questions/6307266/linux-need-accurate-program-timing-scheduler-wake-up-program ? – jxh Feb 28 '13 at 19:10
  • 1
    Here's a method that gives you microsecond precision (not guaranteed but reliable) http://stackoverflow.com/questions/14944204/linux-hrtimer-microsecond-precision/14944464#14944464 – amdn Feb 28 '13 at 20:28

5 Answers5

5

It almost doesn't matter what you are going to use — a select(), epoll(), usleep(), settimer(). Some methods can "take" a higher-resolution timeout, some can't. But Linux is not a real-time OS and should not even expect it to wake up your process at precisely that time. Now, even if you spin the CPU, the kernel can easily suspend your process shall it decide to allocate that CPU to some other process or an interrupt handler.

From the API perspective (as well as recent trends), you should probably stick with timerfd() — you can tell it what clock to use, and it integrates nicely with the rest of Linux event dispatching mechanisms (epoll, AIO, etc).

Other than that, its outside your control as a programmer. A great effort is usually needed in order to get near-real-time behavior from Linux. It ranges from building a custom patched kernel and configuring affinity for the entire world including shielding of interrupts, to patching your BIOS and tuning the hardware.

As it is, assuming you run a fresh vanilla kernel on a commodity x86_64 server which is not highly loaded, expect your wake-up time to be somewhere around 50 µs (you can easily benchmark it to get a rough idea for your system).

3

Running on a non-realtime OS, no userspace approach is entirely reliable. You're right that sleeping is imprecise and you may oversleep, but the same applies to looping: the OS may not schedule your task in time, and you'll miss your slot.

Depending on how reliable you need this to be, consider a real-time operating system (RTOS) like QNX or RTLinux. RTLinux's wiki is a bit out of date, so I am not sure how active it is.

Another approach is to rely on the timing of some hardware device (such as a GPS card). Your program would react to the external event rather than try to time itself. For example, the hardware device could expose a "file". Your program would open it and block on read(). Every 100 ms, the hardware device sends some data to you.

Philip
  • 1,532
  • 12
  • 23
1

You could try RTAI, the Real Time Application Interface for Linux.

[...] which lets you write applications with strict timing constraints for your favourite operating system. Like Linux itself this software is a community effort.

From the beginners guide:

RTAI offers the same services of the Linux kernel core, adding the features of an industrial real time operating system. It consists basically of an interrupt dispatcher: RTAI mainly traps the peripherals interrupts and if necessary re-routes them to Linux. It is not an intrusive modification of the kernel; it uses the concept of HAL (hardware abstraction layer) to get information from Linux and to trap some fundamental functions. This HAL provides few dependencies to Linux Kernel. This leads to a simple adaptation in the Linux kernel, an easy RTAI port from version to version of Linux and an easier use of other operating systems instead of RTAI. RTAI considers Linux as a background task running when no real time activity occurs.

Christian Ammer
  • 7,464
  • 6
  • 51
  • 108
0

You might also consider the Linux specific timerfd_create(2) -and friends- (with poll(2) for multiplexing/waiting, or some event library like libev or libevent, or Gtk or Qt event loops, which will call poll internally) or the Posix timer_create(2). See also clock_gettime(2) and friends

I strongly suggest reading time(7) man page. It explains a lot. And as Vlad answered, Linux is not a true real time kernel (even if it may be close).

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
-1

check out libevent: http://libevent.org/

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts.

zzk
  • 1,347
  • 9
  • 15