如何强制线程内的一段代码不间断地运行(防止它被OS抢占)
How to force a piece of code inside a thread to run uninterruptedly (keep it from being preempted by the OS)
对于给定的任务 T 和代码块(包装在此处的方法中)m1、m2 和 m3,
有没有一种方法可以不间断地强制其中任何一个 - 比如 m2 - 到 运行,即线程 运行 在达到其时间片限制时执行此程序,如果在m2 执行的中间,在 m2 完成之前不要离开处理器,然后才为新线程腾出空间?
这可能吗?
示例:
class Program
{
static void Main(string[] args)
{
Task task = new Task(() =>
{
m1();
//I want to assure m2 runs uninterruptedly, i.e., that the running thread does not stop while executing m2
m2();
m3();
});
}
private static void m1()
{
//whatever1...
}
private static void m2()
{
//whatever2...
}
private static void m3()
{
//whatever3...
}
}
回答每个人的 "why did you come up with this?",它在试图找到 this 问题的解决方案时弹出。我的想法:我需要保证我的切换到主 window 句柄不是 interrupted/preempted。
对于我的实际问题,这是否是一个合理的解决方案 - 我认为这个问题值得一问。
没有。您是 运行 您在 preemptive OS 上的代码,因此您无权阻止抢占。
你的真正问题是什么?试着描述一下你遇到的实际问题,为什么你提出这个需求,然后也许有人可以针对你的实际问题提供建议..
更新后
记住这条关于多线程编程的简单经验法则:线程几乎永远不是正确的答案,事件驱动编程几乎总是。除非你有 CPU 密集计算而不是在不同的数据集上扩展,否则很少需要添加线程。生成一个新线程(或任务)只是为了等待 IO(导航到 URL...)是一种反模式。不幸的是,99.999% 的多线程编程示例只是简单地使用线程来简化控制流程。
考虑到这一点,请考虑使用事件驱动模型,例如 EventFiringWebDriver
。你将只有一个线程,你的主线程,并在其中对你的 web 驱动程序事件做出反应(URLs 下载,选项卡打开等)。
必须切换到支持实时扩展的嵌入式版本 windows。即使那样,您也需要从 C# 切换到本地语言才能使用这些计划功能。
您能做的最好的事情是在 m2
执行期间更改 thread's priority 以使其 不太可能 它被安排离开。但是,如果你打算这样做,你不应该使用 Task.Run
而应该使用实际的 Thread
对象,你不应该更改 ThreadPool 线程的优先级(这是 Task.Run
使用的)。
在这种情况下,正确答案取决于您为什么要尝试做您所要求的事情。正确地做到这一点比听起来要难得多。
一般情况下,是的。您可以通过多种方式实现这一目标。但是,根据上下文,我假设您想知道是否可以在股票 Windows OS 上做到这一点。最简洁的答案是不。 Windows 有一个抢占式多任务内核,用户进程无法阻止它在时间片结束时中断线程。
然而,这还不是全部。您可以将线程的优先级设置为 "REALTIME",这将防止它被任何其他线程抢占。调度器仍然会抢占你,但因为没有其他人有更高的优先级,它会马上返回给你。 document 解释了如何做到这一点。
请注意,这被认为是 一个坏主意。 如果管理不当,它将接管整个机器并使其尖叫停止。
对于大多数用户,建议使用Multimedia Class Scheduling Service
如果您的软件确实需要实时服务(也就是说,能够 运行 对服务质量有硬性保证的东西),您可以查看 Windows 的实时扩展或Linux,或像 vxWorks or QNX.
这样的完全实时系统之一
对于给定的任务 T 和代码块(包装在此处的方法中)m1、m2 和 m3,
有没有一种方法可以不间断地强制其中任何一个 - 比如 m2 - 到 运行,即线程 运行 在达到其时间片限制时执行此程序,如果在m2 执行的中间,在 m2 完成之前不要离开处理器,然后才为新线程腾出空间?
这可能吗?
示例:
class Program
{
static void Main(string[] args)
{
Task task = new Task(() =>
{
m1();
//I want to assure m2 runs uninterruptedly, i.e., that the running thread does not stop while executing m2
m2();
m3();
});
}
private static void m1()
{
//whatever1...
}
private static void m2()
{
//whatever2...
}
private static void m3()
{
//whatever3...
}
}
回答每个人的 "why did you come up with this?",它在试图找到 this 问题的解决方案时弹出。我的想法:我需要保证我的切换到主 window 句柄不是 interrupted/preempted。
对于我的实际问题,这是否是一个合理的解决方案 - 我认为这个问题值得一问。
没有。您是 运行 您在 preemptive OS 上的代码,因此您无权阻止抢占。
你的真正问题是什么?试着描述一下你遇到的实际问题,为什么你提出这个需求,然后也许有人可以针对你的实际问题提供建议..
更新后
记住这条关于多线程编程的简单经验法则:线程几乎永远不是正确的答案,事件驱动编程几乎总是。除非你有 CPU 密集计算而不是在不同的数据集上扩展,否则很少需要添加线程。生成一个新线程(或任务)只是为了等待 IO(导航到 URL...)是一种反模式。不幸的是,99.999% 的多线程编程示例只是简单地使用线程来简化控制流程。
考虑到这一点,请考虑使用事件驱动模型,例如 EventFiringWebDriver
。你将只有一个线程,你的主线程,并在其中对你的 web 驱动程序事件做出反应(URLs 下载,选项卡打开等)。
必须切换到支持实时扩展的嵌入式版本 windows。即使那样,您也需要从 C# 切换到本地语言才能使用这些计划功能。
您能做的最好的事情是在 m2
执行期间更改 thread's priority 以使其 不太可能 它被安排离开。但是,如果你打算这样做,你不应该使用 Task.Run
而应该使用实际的 Thread
对象,你不应该更改 ThreadPool 线程的优先级(这是 Task.Run
使用的)。
在这种情况下,正确答案取决于您为什么要尝试做您所要求的事情。正确地做到这一点比听起来要难得多。
一般情况下,是的。您可以通过多种方式实现这一目标。但是,根据上下文,我假设您想知道是否可以在股票 Windows OS 上做到这一点。最简洁的答案是不。 Windows 有一个抢占式多任务内核,用户进程无法阻止它在时间片结束时中断线程。
然而,这还不是全部。您可以将线程的优先级设置为 "REALTIME",这将防止它被任何其他线程抢占。调度器仍然会抢占你,但因为没有其他人有更高的优先级,它会马上返回给你。 document 解释了如何做到这一点。
请注意,这被认为是 一个坏主意。 如果管理不当,它将接管整个机器并使其尖叫停止。
对于大多数用户,建议使用Multimedia Class Scheduling Service
如果您的软件确实需要实时服务(也就是说,能够 运行 对服务质量有硬性保证的东西),您可以查看 Windows 的实时扩展或Linux,或像 vxWorks or QNX.
这样的完全实时系统之一