根据优先级强制Win32线程调度到定义的序列

Ric*_*ard 6 c winapi multithreading visual-studio-2010

我是一名嵌入式程序员,试图使用Visual Studio 2010和MingW(作为两个独立的构建环境)在Win32环境中模拟实时抢占式调度程序.我在Win32调度环境中非常环保,并且在我尝试做的事情上遇到了障碍.我并不是想要实现实时行为 - 只是为了使模拟任务以与在真实目标硬件上相同的顺序和顺序运行.

正在模拟的实时调度程序有一个简单的目标 - 始终执行能够运行的最高优先级任务(线程).一旦任务变得能够运行 - 它必须抢占当前正在运行的任务,如果它的优先级高于当前正在运行的任务.任务可以由于它正在等待的外部事件而运行,或者超时/阻塞时间/休眠时间到期 - 使用勾选中断生成时基.

除了这种抢占行为之外,任务还可以产生或自愿放弃其时间片,因为正在执行睡眠或等待类型功能.

我通过为正在模拟的实时调度程序创建的每个任务创建一个低优先级的Win32线程来模拟这个(该线程有效地完成了调度程序在真正的嵌入式目标上执行的上下文切换),中等优先级的Win32线程作为伪中断处理程序(处理模拟的节拍中断和产生使用Win32事件对象发出信号的请求),以及更高优先级的Win32线程来模拟生成节拍中断的外设.

当伪中断处理程序确定应该发生任务切换时,它使用SuspendThread()挂起当前正在执行的线程,并使用ResumeThread()恢复执行新选择任务的线程.在可能创建的许多任务及其关联的Win32线程中,只有一个管理任务的线程在任何时候都将处于挂起状态.

重要的是,挂起的线程会立即挂起调用SuspendThread(),并且一旦事件告诉中断处于挂起状态就会执行伪中断处理线程 - 但这不是我看到的行为.

作为我已经解决的一个示例问题:当一个任务/线程产生yield时,事件被锁存在一个变量中,并且中断处理线程被发出信号,因为存在需要处理的伪中断(yield).现在,在我习惯编程的实时系统中,我希望中断处理线程能够立即执行,因为它具有比发出信号的线程更高的优先级.我在Win32环境中看到的是,发出优先级较高的线程的线程在被挂起之前会持续一段时间 - 要么是因为在发出信号的高优先级线程开始执行之前需要一些时间,要么因为暂停需要一些时间实际上停止运行的任务 - 我不确定是哪一个.在任何情况下,通过在信号通知Win32中断处理线程之后在信号量上创建信号Win32线程块并且让中断处理Win32线程在其完成其功能(握手)时解除阻塞,可以很容易地纠正这种情况.有效地使用线程同步来强制调度模式到我需要的.我正在使用SignalObjectAndWait()来实现此目的.

使用这种技术,当模拟的实时调度程序在协作模式下运行时,模拟可以完美地工作 - 但在抢先模式下不是(根据需要).

抢先任务切换的问题我猜是一样的,任务在被告知暂停之后继续执行一段时间才真正停止运行,因此当运行的线程无法保证系统保持一致状态任务暂停.但是在抢先的情况下,因为任务不知道它何时会发生,所以不能使用相同的使用信号量来阻止Win32继续下一次恢复的技术.

有没有人在这篇文章中做到这一点 - 抱歉它的长度!

我的问题是:

  • 我如何强制Win32(XP)调度立即启动和停止任务,调用挂起和恢复线程函数 - 或 - 如何强制更高优先级的Win32线程立即开始执行它能够这样做(对象被阻止的信号).有效地迫使Win32重新安排其运行进程.

  • 当某个事件不在任务/线程顺序执行路径中时,是否存在某种异步停止任务以等待事件的方法.

  • 模拟器在Linux环境中运行良好,其中POSIX信号用于有效地中断线程 - 在Win32中是否存在等价物?

感谢任何花时间阅读这篇长篇文章的人,特别感谢任何可以让我的"实时工程师"通过这个Win32迷宫的人.

Rem*_*eau 5

如果您需要自己进行调度,那么您可以考虑使用光纤而不是线程.光纤类似于线程,因为它们是可执行代码的单独块,但是光纤可以在用户代码中调度,而线程仅由OS调度.单个线程可以托管和管理多个光纤的调度,并且光纤甚至可以相互调度.