You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于POSIX线程的C语言每20ms周期性启动方法方案咨询

Strict Periodic Execution with POSIX Threads (C)

Alright, let's tackle this precise 20ms task scheduling problem—no more of that "run task then wait 20ms" drift caused by your task's execution time X. The core fix here is to schedule each task start based on a fixed absolute timeline, not relative to when the last task finished. Here's how to implement it properly:

Key Principles

  • Use a monotonic clock: CLOCK_MONOTONIC is critical here because it never jumps backward (even if system time is adjusted manually or via NTP), ensuring stable, unbroken periodicity.
  • Wait for an absolute time point: Instead of sleeping for 20ms after a task ends, calculate exactly when the next task should start and wait until that exact moment.

Full Implementation Code

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>
#include <errno.h>

#define PERIOD_NS (20LL * 1000LL * 1000LL) // 20ms converted to nanoseconds

// Replace this with your actual task logic
void run_periodic_task() {
    // Example: Print the exact start time (in ms) using the monotonic clock
    struct timespec now;
    clock_gettime(CLOCK_MONOTONIC, &now);
    long long current_ms = now.tv_sec * 1000LL + now.tv_nsec / 1000000LL;
    printf("Task started at %lld ms\n", current_ms);

    // Your task code here (even if it takes variable time X)
    // ...
}

void* periodic_thread_func(void* arg) {
    struct timespec next_start_time;
    int sleep_result;

    // Initialize the first start time to the current monotonic time
    if (clock_gettime(CLOCK_MONOTONIC, &next_start_time) != 0) {
        perror("Failed to get initial clock time");
        pthread_exit(NULL);
    }

    while (1) {
        // Execute the task exactly at the scheduled start time
        run_periodic_task();

        // Calculate the next scheduled start time
        next_start_time.tv_nsec += PERIOD_NS;
        // Handle nanosecond overflow (since 1 second = 1e9 nanoseconds)
        while (next_start_time.tv_nsec >= 1000000000LL) {
            next_start_time.tv_sec += 1;
            next_start_time.tv_nsec -= 1000000000LL;
        }

        // Wait until the next start time—retry if interrupted by a signal
        do {
            sleep_result = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next_start_time, NULL);
        } while (sleep_result == EINTR);

        // Optional: Add a termination flag check here (e.g., if arg points to a stop signal)
        // if (*(int*)arg) break;
    }

    pthread_exit(NULL);
}

int main() {
    pthread_t periodic_thread;
    int thread_create_result;

    thread_create_result = pthread_create(&periodic_thread, NULL, periodic_thread_func, NULL);
    if (thread_create_result != 0) {
        perror("Failed to create periodic thread");
        return EXIT_FAILURE;
    }

    // Wait for the thread to finish (this example runs indefinitely)
    pthread_join(periodic_thread, NULL);

    return EXIT_SUCCESS;
}

How It Works

  1. Initialization: We grab the current monotonic time to set the first task's start point.
  2. Task Execution: The task runs exactly at the precomputed start time.
  3. Schedule Next Run: We add 20ms to the last start time (not the task's end time) and adjust for nanosecond overflow to keep the time valid.
  4. Precise Waiting: clock_nanosleep with the TIMER_ABSTIME flag waits until the exact next start time. If a signal interrupts the sleep, we retry immediately to avoid missing the window.

Handling Long-Running Tasks

If your task takes longer than 20ms (e.g., X=30ms), clock_nanosleep will return immediately (since the next start time has already passed). The task will run again right away, and subsequent starts will realign to the original 20ms timeline—no cumulative drift.

Compilation Tip

When compiling, link against the POSIX threads library:

gcc your_file.c -o periodic_task -pthread -lrt

内容的提问来源于stack exchange,提问作者MaMa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:52:28