如何在C++中用线程实现优先级抢占式调度(类似于中断)
How to implement Priority Preemptive Scheduling (similar to interrupts) with threads in C++
我想在 Windows 上编写一个 C++ 程序(但最好支持跨平台),其中我有两个基于 Priority Preemptive Scheduling 调度的线程 - 这就像一个中断行为(当中断发生时,主线程会在任何地方暂停,只有当中断线程回到睡眠状态时,主线程才会从暂停的地方恢复)。
这些是线程:
- 线程T_main
- 线程 T_interrupt.
T_main 运行s 一直在 while 循环中。
T_interrupt 应该每秒执行一次,而且速度非常快。
T_main中的代码比较大(数千行代码)。
时间一定非常准确。
我希望当 T_interrupt 线程到 运行 的时间到来时,它会被优先处理,以便它 运行 不会中断,直到它完成,然后才线程T_main 将从暂停的地方恢复。
如果你想知道我在做什么,那么这里有一个基本的解释:
基本上,我正在 运行 模拟我的嵌入式项目。我模拟了我的整个硬件,我想 运行 在 PC 的模拟器上运行我的应用程序。目的是测试我的应用程序的逻辑实现。考虑了编译器差异和其他缺陷。对我来说至关重要的是能够模拟存在于我的 MCU 上的基于 1 秒滴答定时器的中断。我发现很难模拟这种行为,因为线程调度似乎是合作的而不是抢占式的。
我尝试使用优先级和设置调度方法,例如 Round Robin SCHED_RR
或 FIFO 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, SCHED_FIFO, 20);
T_main.join();
T_interrupt.join();
}
我找到了几个解决这个问题的方法,我想我会在这里与其他人分享。在整个 Whosebug 中,我发现其他人问过与此类似的问题,并且有几种可能的解决方案。
使用线程实现中断行为的可能解决方案:
- 在您的线程上强制进行上下文切换。我在 Windows 上找到了一些关于如何执行此操作的有用参考,如 FreeRTOS Windows Simulator 中所述。就我个人而言,这似乎是最好的选择。而且,我可能只使用这个模拟器而不是自己构建。
- 编写一个 windows 驱动程序,如下所述:
- 使用 SuspendThread and ResumeThread. Although when using this method you should be aware that they are async in nature as depicted here 所以这并不理想。
我想在 Windows 上编写一个 C++ 程序(但最好支持跨平台),其中我有两个基于 Priority Preemptive Scheduling 调度的线程 - 这就像一个中断行为(当中断发生时,主线程会在任何地方暂停,只有当中断线程回到睡眠状态时,主线程才会从暂停的地方恢复)。
这些是线程:
- 线程T_main
- 线程 T_interrupt.
T_main 运行s 一直在 while 循环中。 T_interrupt 应该每秒执行一次,而且速度非常快。
T_main中的代码比较大(数千行代码)。
时间一定非常准确。
我希望当 T_interrupt 线程到 运行 的时间到来时,它会被优先处理,以便它 运行 不会中断,直到它完成,然后才线程T_main 将从暂停的地方恢复。
如果你想知道我在做什么,那么这里有一个基本的解释: 基本上,我正在 运行 模拟我的嵌入式项目。我模拟了我的整个硬件,我想 运行 在 PC 的模拟器上运行我的应用程序。目的是测试我的应用程序的逻辑实现。考虑了编译器差异和其他缺陷。对我来说至关重要的是能够模拟存在于我的 MCU 上的基于 1 秒滴答定时器的中断。我发现很难模拟这种行为,因为线程调度似乎是合作的而不是抢占式的。
我尝试使用优先级和设置调度方法,例如 Round Robin SCHED_RR
或 FIFO 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, SCHED_FIFO, 20);
T_main.join();
T_interrupt.join();
}
我找到了几个解决这个问题的方法,我想我会在这里与其他人分享。在整个 Whosebug 中,我发现其他人问过与此类似的问题,并且有几种可能的解决方案。
使用线程实现中断行为的可能解决方案:
- 在您的线程上强制进行上下文切换。我在 Windows 上找到了一些关于如何执行此操作的有用参考,如 FreeRTOS Windows Simulator 中所述。就我个人而言,这似乎是最好的选择。而且,我可能只使用这个模拟器而不是自己构建。
- 编写一个 windows 驱动程序,如下所述:
- 使用 SuspendThread and ResumeThread. Although when using this method you should be aware that they are async in nature as depicted here 所以这并不理想。