【发布时间】:2010-11-18 18:54:44
【问题描述】:
我是一名嵌入式程序员,尝试使用 Visual Studio 2010 和 MingW(作为两个独立的构建环境)在 Win32 环境中模拟实时抢占式调度程序。我对 Win32 调度环境非常熟悉,并且我正在尝试做的事情已经碰壁了。我不是试图实现实时行为——只是为了让模拟任务以与在真实目标硬件上相同的顺序和顺序运行。
正在模拟的实时调度程序有一个简单的目标 - 始终执行能够运行的最高优先级任务(线程)。一旦任务能够运行 - 如果它的优先级高于当前运行的任务,它必须抢占当前运行的任务。由于正在等待的外部事件,或者超时/阻塞时间/睡眠时间到期,任务可能会变得能够运行 - 带有生成时基的滴答中断。
除了这种先发制人的行为,一个任务可以让步或自愿放弃它的时间片,因为它正在执行一个睡眠或等待类型的函数。
我通过为正在模拟的实时调度程序创建的每个任务创建一个低优先级 Win32 线程来模拟这一点(该线程有效地执行调度程序将在真实嵌入式目标上执行的上下文切换),中等优先级 Win32线程作为伪中断处理程序(处理模拟滴答中断和使用 Win32 事件对象向其发送信号的产生请求),以及更高优先级的 Win32 线程来模拟生成滴答中断的外围设备。
当伪中断处理程序确定应该发生任务切换时,它使用 SuspendThread() 挂起当前正在执行的线程,并使用 ResumeThread() 恢复执行新选择的任务的线程。在可能创建的许多任务及其相关联的 Win32 线程中,只有一个管理该任务的线程在任何时候都会脱离挂起状态。
重要的是,挂起的线程在调用 SuspendThread() 时立即挂起,并且伪中断处理线程在通知它中断挂起的事件发出信号后立即执行 - 但这不是我的行为看到。
作为一个我已经解决的示例问题:当任务/线程产生时,产生事件被锁定在变量中,并且中断处理线程发出信号,因为存在需要处理的伪中断(产生) .现在在我习惯于编程的实时系统中,我希望中断处理线程在收到信号后立即执行,因为它比发出信号的线程具有更高的优先级。我在 Win32 环境中看到的是,发出高优先级线程信号的线程在被挂起之前会持续一段时间——要么是因为在发出信号的高优先级线程开始执行之前需要一些时间,要么是因为挂起需要一些时间实际停止运行的任务 - 我不确定哪个。在任何情况下,通过在发出 Win32 中断处理线程信号后使信号量上的信号量 Win32 线程阻塞,并让中断处理 Win32 线程在完成其功能(握手)时解除阻塞线程,这可以很容易地纠正。有效地使用线程同步来强制调度模式符合我的需要。为此,我正在使用 SignalObjectAndWait()。
使用这种技术,当被模拟的实时调度程序在协作模式下运行时,模拟工作完美 - 但不是(根据需要)在抢占模式下。
抢占式任务切换的问题我猜是一样的,任务在被告知暂停后会继续执行一段时间,然后才真正停止运行,因此无法保证系统在运行时保持一致状态运行任务的线程挂起。但在抢占式情况下,由于任务不知道它何时会发生,因此无法使用使用信号量来阻止 Win32 线程继续直到下一次恢复的相同技术。
有没有人把这篇文章写到这么远 - 很抱歉它的长度!
那么我的问题是:
如何强制 Win32 (XP) 调度立即启动和停止调用挂起和恢复线程函数的任务 - 或者 - 我如何强制更高优先级的 Win32 线程立即开始执行它能够这样做(它被阻止的对象发出信号)。有效地强制 Win32 重新安排其正在运行的进程。
当任务不在任务/线程顺序执行路径中时,是否有某种方法可以异步停止任务以等待事件。
模拟器在使用 POSIX 信号有效中断线程的 Linux 环境中运行良好 - 在 Win32 中是否有等效项?
感谢所有花时间阅读这篇长文的人,特别感谢任何可以牵着我的“实时工程师”手穿过这个 Win32 迷宫的人。
【问题讨论】:
标签: c multithreading winapi visual-studio-2010