title: What is the best way to create periodic Linux threads in C
body: <p>For my application I have the requirement of accurate periodic threads with relative low cycle times (500 µs).<br>
  In particular the application is a run time system of a 
  <a href="https://en.wikipedia.org/wiki/Programmable_logic_controller" rel="nofollow noreferrer">PLC</a>.
  It's purpose is to run an application developed by the PLC user.
  Such applications are organised in programs and periodic tasks - each task with it's own cycle time and priority.<br>
  Usually the application runs on systems with real time OSs (eg. vxWorks or Linux with RT patch). </p>
  
  <p>Currently the periodic tasks are implemented via <code>clock_nanosleep</code>.
  Unfortunately the actual sleep time of <code>clock_nanosleep</code> is disturbed by other threads - even with lower priority.
  Once every second, the sleep time is exceeded by about 50 ms.
  I've observed this on Debian 9.5, on RaspberryPi and also on an ARM-Linux with Preemt-RT.</p>
  
  <p>Here's a sample, which shows this behavior:</p>
  
  <pre><code>#include &lt;pthread.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;stdint.h&gt;
  #include &lt;stdio.h&gt;
  
  typedef void* ThreadFun(void* param);
  
  #define SCHEDULER_POLICY    SCHED_FIFO
  #define CLOCK CLOCK_MONOTONIC
  #define INTERVAL_NS       (10 * 1000 * 1000)
  
  static long tickCnt = 0;
  
  static long calcTimeDiff(struct timespec const* t1, struct timespec const* t2)
  {
    long diff = t1-&gt;tv_nsec - t2-&gt;tv_nsec;
    diff += 1000000000 * (t1-&gt;tv_sec - t2-&gt;tv_sec);
    return diff;
  }
  
  static void updateWakeTime(struct timespec* time)
  {
    uint64_t nanoSec = time-&gt;tv_nsec;
    struct timespec currentTime;
  
    clock_gettime(CLOCK, &amp;currentTime);
    while (calcTimeDiff(time, &amp;currentTime) &lt;= 0)
    {
      nanoSec = time-&gt;tv_nsec;
      nanoSec += INTERVAL_NS;
      time-&gt;tv_nsec = nanoSec % 1000000000;
      time-&gt;tv_sec += nanoSec / 1000000000;
    }
  }
  
  static void* tickThread(void *param)
  {
    struct timespec sleepStart;
    struct timespec currentTime;
    struct timespec wakeTime;
    long sleepTime;
    long wakeDelay;
  
    clock_gettime(CLOCK, &amp;wakeTime);
    wakeTime.tv_sec += 2;
    wakeTime.tv_nsec = 0;
  
    while (1)
    {
      clock_gettime(CLOCK, &amp;sleepStart);
      clock_nanosleep(CLOCK, TIMER_ABSTIME, &amp;wakeTime, NULL);
      clock_gettime(CLOCK, &amp;currentTime);
      sleepTime = calcTimeDiff(&amp;currentTime, &amp;sleepStart);
      wakeDelay = calcTimeDiff(&amp;currentTime, &amp;wakeTime);
      if (wakeDelay &gt; INTERVAL_NS)
      {
        printf("sleep req=%-ld.%-ld start=%-ld.%-ld curr=%-ld.%-ld sleep=%-ld delay=%-ld\n",
            (long) wakeTime.tv_sec, (long) wakeTime.tv_nsec,
            (long) sleepStart.tv_sec, (long) sleepStart.tv_nsec,
            (long) currentTime.tv_sec, (long) currentTime.tv_nsec,
            sleepTime, wakeDelay);
      }
      tickCnt += 1;
      updateWakeTime(&amp;wakeTime);
    }
  }
  
  static void* workerThread(void *param)
  {
    while (1)
    {
    }
  }
  
  static int createThread(char const* funcName, ThreadFun* func, int prio)
  {
    pthread_t tid = 0;
    pthread_attr_t threadAttr;
    struct sched_param schedParam;
  
    printf("thread create func=%s prio=%d\n", funcName, prio);
  
    pthread_attr_init(&amp;threadAttr);
    pthread_attr_setschedpolicy(&amp;threadAttr, SCHEDULER_POLICY);
    pthread_attr_setinheritsched(&amp;threadAttr, PTHREAD_EXPLICIT_SCHED);
    schedParam.sched_priority = prio;
    pthread_attr_setschedparam(&amp;threadAttr, &amp;schedParam);
  
    if (pthread_create(&amp;tid, &amp;threadAttr, func, NULL) != 0)
    {
      return -1;
    }
  
    printf("thread created func=%s prio=%d\n", funcName, prio);
    return 0;
  }
  #define CREATE_THREAD(func,prio)  createThread(#func,func,prio)
  
  
  int main(int argc, char*argv[])
  {
    int minPrio = sched_get_priority_min(SCHEDULER_POLICY);
    int maxPrio = sched_get_priority_max(SCHEDULER_POLICY);
    int prioRange = maxPrio - minPrio;
  
    CREATE_THREAD(tickThread, maxPrio);
    CREATE_THREAD(workerThread, minPrio + prioRange / 4);
    sleep(10);
    printf("%ld ticks\n", tickCnt);
  }
  </code></pre>
  
  <p>Is something wrong in my code sample?</p>
  
  <p>Is there a better (more reliable) way to create periodic threads?</p>