Выполнить задачу cycli c используя потоки posix - PullRequest
0 голосов
/ 19 марта 2020

Я ищу решение для запуска метода каждые 20 мс. Я нашел некоторые решения для c ++, но все еще ищу решение в c, которое использует потоки posix. Я не хочу выполнять метод и ждать n миллисекунд, так как это займет 20 мс + X. Я действительно хочу запускать каждые 20 мс .. Кто-нибудь имеет какие-либо идеи?

Ответы [ 3 ]

1 голос
/ 20 марта 2020

Функция clock_nanosleep() POSIX имеет режим абсолютного крайнего срока:

#define NSEC_PER_SEC 1000000000
/* Initial delay, 7.5ms */
const long start_delay_ns = 7500000;
/* Cycle time, 20ms */
const long cycle_time_ns = 20000000;
struct timespec deadline;

clock_gettime(CLOCK_MONOTONIC, &deadline);
deadline.tv_nsec += start_delay_ns;
deadline.tv_sec += deadline.tv_nsec / NSEC_PER_SEC;
deadline.tv_nsec %= NSEC_PER_SEC;

for (;;)
{
    struct timespec now;

    /* Sleep until deadline */
    while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0)
        if (errno != EINTR)
            return; /* error handling here */

    cyclic_function(arguments);    /* Your cyclic function */

    /* Calculate next deadline */
    deadline.tv_nsec += cycle_time_ns;
    deadline.tv_sec += deadline.tv_nsec / NSEC_PER_SEC;
    deadline.tv_nsec %= NSEC_PER_SEC;

    clock_gettime(CLOCK_MONOTONIC, &now);
    if (now.tv_sec > deadline.tv_sec || (now.tv_sec == deadline.tv_sec && deadline.tv_nsec > now.tv_nsec))
        return; /* time overrun error handling here */
}
1 голос
/ 19 марта 2020

timer_create(), timer_settime()it_interval) и sigsuspend() - при условии, что метод не выходит за интервал 20 мс.

0 голосов
/ 19 марта 2020

за n миллисекунд, так как это займет 20 мс + X

Это всегда займет немного больше времени. Единственное, что вы можете сделать, это точно измерить интервал между выполнениями.

Использовать timer_create() и указать интервал в 20 миллисекунд:

#define _GNU_SOURCE
#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>

#define fatal(fmt, ...) do{ fprintf(stderr, "%d:%d" fmt "\n", __LINE__, errno, ##__VA_ARGS__); abort(); } while(0)

void method(union sigval sv) {
    int *num = sv.sival_ptr;
    printf("Hello %d\n", (*num)++);
}

int main() {
    int ctx = 100;
    struct sigevent sevp = {
       .sigev_notify = SIGEV_THREAD,
       .sigev_notify_function = method,
       .sigev_value = {
           .sival_ptr = &ctx,
       },
    };
    timer_t tm;
    int err = timer_create(CLOCK_MONOTONIC, &sevp, &tm);
    if (err) fatal("timer_create");
    const struct timespec ts_20_ms = {
        .tv_sec = 0,
        .tv_nsec = 20000000,
    };
    err = timer_settime(tm, 0, &(const struct itimerspec){
        .it_interval = ts_20_ms,
        .it_value = ts_20_ms,
    }, NULL);
    if (err) fatal("timer_settime");
    usleep(1 * 1000 * 1000);
    err = timer_delete(tm);
    if (err) fatal("timer_delete");
    exit(0);
}
...