在多线程服务器程序中使用linux信号处理程序每​​25ms执行一次浮点计算的程序的实现?

时间:2016-12-07 16:20:35

标签: c linux multithreading pthreads signals

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

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

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

很抱歉很长的解释,但我觉得一个很好的解释会产生一个很好的答案。

感谢您的时间!

2 个答案:

答案 0 :(得分:1)

正如您所指出的那样,在信号处理程序中进行任何类型的工作都会令人恼火。为了避免这种烦恼,我会产生另一个线程(如果你有空间),并让该线程等待信号量。然后,您可以从信号处理程序发送到该信号量,以唤醒您的处理线程。

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

答案 1 :(得分: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;
}

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

在实践中,这可以为您提供非常好的延迟结果。