2016-12-07 8 views
1

Моя цель: мне нужно вычислить новые управляющие входы моей системы и обновить положение робота, который я программирую, в точные моменты выборки.Реализация программы для выполнения вычислений с плавающей запятой каждые 25 мс с использованием обработчика сигнала linux в многопоточной программе сервера?

Проблема: у меня есть работающая серверная программа, которая обслуживает несколько клиентов и может выполнять простые маневры роботов. Для этого у меня есть два потока: один для управления роботом и один для обслуживания нескольких клиентов. Теперь мне нужно внедрить более сложные алгоритмы роя в точные образцы моментов. Я успешно написал боковую программу (используя setitimer()), которая прерывает каждые 25 мс, используя SIGVTALRM.

Теперь мне нужен совет о том, как лучше всего приступить к проектированию. Мое основное беспокойство заключается в том, как выполнить алгоритм в обработчике сигнала, поскольку он должен удовлетворять многим ограничениям из-за многопоточных и безопасных сигналов.

Извините за подробные объяснения, но я считаю, что хорошее объяснение даст хороший ответ.

Спасибо за ваше время!

+0

Насколько точны сроки? + - 1 мс? + - 10 мс? –

+0

+ - 0,1 мс будет достаточно хорошим. – lukecam95

+1

Вы смотрели 'timer_create' и' timer_settime'? –

ответ

1

Как вы указываете, выполнение каких-либо работ в обработчике сигнала вызывает раздражение. Чтобы избежать раздражения, я бы породил еще один поток (если у вас есть место для него), и ожидание этого потока на семафоре. Затем вы можете отправить сообщение на этот семафор из вашего обработчика сигнала, чтобы разбудить поток обработки.

Это все равно будет подвержено джиттеру из планировщика, и я не уверен (без какого-либо тестирования), сможет ли он удовлетворить ваш срок 100%, но это стоит того.

+0

Очень полезно! Спасибо :) – lukecam95

0

Я согласен с тем, что выполнение работы в обработчике сигналов следует избегать, особенно в многопоточном приложении. Очень мало вы можете безопасно выполнять в среде асинхронного сигнала в POSIX.

Я хотел бы избежать использования сигналов на всех: вы можете просто породит поток, который ждет на следующий срок, прежде чем выполнять необходимую работу, а затем петли вокруг ждать снова:

#include <time.h> 
#include <errno.h> 

void *timed_calculation_thread(void *ptr) 
{ 
    struct timespec deadline; 

    clock_gettime(CLOCK_MONOTONIC, &deadline); 

    while(1) 
    { 
     /* Perform floating point calculations, update robot state 
     * etc. here */ 

     /* Add 25ms to previous deadline */ 
     deadline.tv_nsec += 25000000; 
     deadline.tv_sec += deadline.tv_nsec/1000000000; 
     deadline.tv_nsec %= 1000000000; 
     /* Sleep until new deadline */ 
     while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &deadline, NULL) != 0) 
      if (errno != EINTR) return NULL; 
    } 

    return NULL; 
} 

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

На практике это может дать вам неплохие результаты задержек.

+0

Спасибо, попробуй и дайте знать :)! – lukecam95