【问题标题】:Implementation of a program to carry out floating point calculations every 25ms using a linux signal handler in a multi-threaded server program?在多线程服务器程序中使用linux信号处理程序每​​25ms执行一次浮点计算的程序的实现?
【发布时间】:2016-12-07 16:20:34
【问题描述】:

我的目标:我需要计算我的系统的新控制输入,并在精确的采样时刻更新我正在编程的机器人的位置。

问题背景:我有一个功能正常的服务器程序,可以为多个客户端提供服务,并且可以进行简单的机器人操作。为此,我有两个线程,一个用于控制机器人,一个用于服务多个客户端。现在我需要在精确的采样时刻实现更复杂的群算法。我已经成功编写了一个使用 SIGVTALRM 每 25 毫秒中断一次的辅助程序(使用 setitimer() )。

现在我需要关于如何最好地进行设计的建议。我主要担心的是如何在信号处理程序中执行算法,因为由于多线程和信号安全功能,它必须满足许多约束。

对不起,解释太长了,但我觉得一个好的解释会产生一个好的答案。

感谢您的宝贵时间!!

【问题讨论】:

  • 时间需要有多精确? +- 1 毫秒? +- 10 毫秒?
  • +- 0.1ms 就足够了。
  • 你看过timer_createtimer_settime吗?
  • 我已经简要地阅读了它们,但没有详细研究它们。与 setitimer() 方法相比,它们有什么特别的优势吗?谢谢

标签: c linux multithreading pthreads signals


【解决方案1】:

正如您所指出的,在信号处理程序中做任何类型的工作都是令人讨厌的。为了避免刺激,我会产生另一个线程(如果你有空间的话),并让那个线程在信号量上等待。然后,您可以从信号处理程序发布到该信号量以唤醒您的处理线程。

这仍然会受到调度程序的影响,而且我不确定(没有做一些测试)这是否能够满足您的 100us 截止日期,但值得一试。

【讨论】:

  • 非常有帮助!谢谢:)
【解决方案2】:

我同意应避免在信号处理程序中执行工作,尤其是在多线程应用程序中。在 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;
}

如果您的进程以足够的权限运行,您还可以为该线程提供实时调度类(如有必要)。

实际上,这可以为您提供相当好的延迟结果。

【讨论】:

  • 谢谢,会试一试,让你知道:)!
猜你喜欢
  • 2016-03-21
  • 2021-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-04
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
相关资源
最近更新 更多