C++中如何用线程实现优先级抢占调度类似于中断

问题描述

我想在 Windows 上编写一个 C++ 程序(但最好支持跨平台),其中我有两个基于 Priority Preemptive Scheduling 调度的线程 - 这就像一个中断行为(当中断发生时,主线程无论在哪里都会暂停,并且只有当中断线程回到睡眠状态时,主线程才会从暂停的地方恢复)。

这些是线程:

  1. 线程 T_main
  2. 线程 T_interrupt。

T_main 一直在 while 循环中运行。 T_interrupt 应该每秒执行一次,并且执行速度非常快。

T_main 中的代码相当大(数千行代码)。

时间必须非常准确。

我希望当 T_interrupt 线程运行的时间到了时,它会被优先处理,这样它就会不间断地运行,直到它完成,然后线程 T_main 才会从它暂停的地方恢复。

如果你想知道我想要做什么,那么这里是一个基本的解释: 基本上,我正在运行我的嵌入式项目的模拟。我模拟了我的整个硬件,我想在 PC 上的模拟器上运行我的应用程序。目的是测试我的应用程序的逻辑实现。编译器差异和其他缺陷都被考虑在内。对我来说至关重要的是能够模拟存在于我的 MCU 上的基于 1 秒滴答定时器的中断。我发现很难模拟这种行为,因为线程调度似乎是合作的而不是抢占的。

我尝试使用优先级和设置调度方法,例如轮循SCHED_RR或先进先出SCHED_FIFO,但在所有情况下调度实现仍然是合作的而不是抢占的。

这是我的代码

#include <iostream>
#include <thread>
#include <pthread.h>
#include <string>

using namespace std;

void MainApplicationFunc(void)
{
    // Infinite loop in which the app is running
    while(1)
    {
        MainProgram();
    }
}

void TickTimerInterruptFunc()
{
    while(1)
    {
        TickTimer();
        std::this_thread::sleep_for(1s);
    }
}

void setScheduling(std::thread &th,int policy,int priority)
{
    sched_param sch_params;
    sch_params.sched_priority = priority;
    if(pthread_setschedparam(th.native_handle(),policy,&sch_params))
    {
        std::cerr << "Failed to set Thread scheduling" << std::endl;
    }
}

int main()
{
    std::thread T_interrupt(TickTimerInterruptFunc);
    setScheduling(T_interrupt,SCHED_FIFO,1);
    std::thread T_main(MainApplicationFunc);
    setScheduling(T_main,20);

    T_main.join();
    T_interrupt.join();
}

解决方法

我为这个问题找到了几个解决方案,我想我会在这里与其他人分享。在整个 stackoverflow 中,我发现其他人提出了与此类似的问题,并且有几种可能的解决方案。

使用线程实现中断行为的可能解决方案:

  1. 在您的线程上强制进行上下文切换。我找到了一些关于如何在 Windows 上执行此操作的有用参考,如 FreeRTOS Windows Simulator 中所述。就我个人而言,这似乎是最好的选择。此外,我可能只是使用这个模拟器而不是自己构建。
  2. 按照此处所述编写 Windows 驱动程序:https://stackoverflow.com/a/13819216/4441211
  3. 使用 SuspendThreadResumeThread。尽管在使用此方法时您应该注意它们本质上是异步的,如图here,因此这并不理想。