问题描述
我想在 Windows 上编写一个 C++ 程序(但最好支持跨平台),其中我有两个基于 Priority Preemptive Scheduling 调度的线程 - 这就像一个中断行为(当中断发生时,主线程无论在哪里都会暂停,并且只有当中断线程回到睡眠状态时,主线程才会从暂停的地方恢复)。
这些是线程:
- 线程 T_main
- 线程 T_interrupt。
T_main 一直在 while 循环中运行。 T_interrupt 应该每秒执行一次,并且执行速度非常快。
时间必须非常准确。
我希望当 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 中,我发现其他人提出了与此类似的问题,并且有几种可能的解决方案。
使用线程实现中断行为的可能解决方案:
- 在您的线程上强制进行上下文切换。我找到了一些关于如何在 Windows 上执行此操作的有用参考,如 FreeRTOS Windows Simulator 中所述。就我个人而言,这似乎是最好的选择。此外,我可能只是使用这个模拟器而不是自己构建。
- 按照此处所述编写 Windows 驱动程序:https://stackoverflow.com/a/13819216/4441211
- 使用 SuspendThread 和 ResumeThread。尽管在使用此方法时您应该注意它们本质上是异步的,如图here,因此这并不理想。