Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows WIN32:让另一个(给定)线程执行_Windows_Multithreading_Winapi - Fatal编程技术网

Windows WIN32:让另一个(给定)线程执行

Windows WIN32:让另一个(给定)线程执行,windows,multithreading,winapi,Windows,Multithreading,Winapi,我正在寻找一种方法,将线程执行计划时间片的剩余部分分配给另一个线程。WINAPI中有一个函数,但它不允许调用方指定要切换到的线程。我在MSDN上浏览了很长一段时间,没有找到任何能提供这一功能的东西 对于像我这样的操作系统内部门外汉来说,线程应该能够指定它希望将执行传递给哪个线程。这是可能的还是我的想象?无法将处理器时间片分配给指定线程的原因是Windows具有一个抢占式调度内核,它几乎将调度处理器时间的责任和权限交给了内核,而只交给了内核 这样的线程无法控制何时运行、是否运行,更不能控制在时间片

我正在寻找一种方法,将线程执行计划时间片的剩余部分分配给另一个线程。WINAPI中有一个函数,但它不允许调用方指定要切换到的线程。我在MSDN上浏览了很长一段时间,没有找到任何能提供这一功能的东西


对于像我这样的操作系统内部门外汉来说,线程应该能够指定它希望将执行传递给哪个线程。这是可能的还是我的想象?

无法将处理器时间片分配给指定线程的原因是Windows具有一个抢占式调度内核,它几乎将调度处理器时间的责任和权限交给了内核,而只交给了内核

这样的线程无法控制何时运行、是否运行,更不能控制在时间片结束后切换到哪个线程

但是,有几种方法可以影响上下文切换:

  • 通过增加某个线程的优先级,您可能会迫使调度程序更频繁地调度该线程,从而损害其他线程(显然,反过来也适用-您可以降低其他线程的优先级)

  • 您可以编写进程代码,在线程没有工作要做时,将线程置于内核等待模式,以帮助调度器完成其工作。当使用适当的内核等待构造(如关键部分、互斥体、信号量和计时器)时,您可以有效地告诉内核,在满足特定的编码之前,不需要调度特定的线程


注意:很少有理由篡改任务优先级,因此请谨慎使用,这是不可能的。只有内核可以决定下一步运行什么代码,尽管您可以通过减少下一步运行时必须选择的非等待线程以及通过设置线程优先级来影响它。

您可以使用常规同步原语(如事件、信号量等)来序列化两个线程。这不会以任何形式阻止内核在两者之间调度其他线程,或在另一个CPU内核上并行调度,或实际上同时在同一个内核上调度。这是由于现代通用操作系统的性质造成的。

您可以使用“光纤”而不是“线程”:例如,有一个名为Win32 API的API,它允许您指定要调度的光纤。

如果您想在Windows下进行自己的调度,您可以使用它,它本质上是您必须自己调度的线程。然而,鉴于您将自己描述为操作系统内部世界的外行,这可能是个坏主意,因为光纤是一种高级功能。

看看Windows 7中的UMS(用户模式调度)线程


第二个线程可以通过在其句柄上调用WaitForSingleObject()或定期轮询GetExitCodeThread()来等待生成的线程。关于更改操作系统的调度机制,其他答案是正确的——最好首先正确设计线程。

我可以问一下为什么要使用SwitchToThread吗

例如,如果它是某种形式的,因为线程x正在计算线程Y上要等待的值,那么我真的建议您查看Visual Studio 2010中的并行模式库或异步代理库,它允许您使用消息块(接收异步值)来执行此操作或者简单地通过任务:等待一组任务完成并在等待时内联执行它们

//i.e. on an arbitrary thread
task_group* tasks;
tasks->run(... / some functor/)

调用tasks->wait()将等待并内联任何正在运行的任务。

即使可以这样做,也不是一个好主意。实际上,您将在自己的应用程序中重写操作系统调度程序。做这样的事是没有好处的@All:同意,这样做可能会导致其他线程(如系统关键线程)饿死,这通常是个坏主意@ChrisW,@dsolimano:我考虑过光纤,但线程只能调度在调度线程上下文中运行的光纤。在这种特殊情况下,我需要在特定线程上执行代码(DirectX需要)@Miky,@Nikolai:谢谢你提出的另一种方法的建议——这正是我所寻找的。我建议你也阅读关于“联合例程”的内容,以了解这方面更多的平台不可知论理论和想法,尽管我认为你最好还是坚持Win32概念,可能是线程而不是光纤。@Marcin,很高兴能提供帮助。如果你想了解更多关于Windows多线程的知识,我建议你买一本Joe Duffy的《Windows并发编程》(Concurrent Programming on Windows)()这本书对初学者和经验丰富的程序员来说都是一本很好的读物。嘿,我并不会造成任何严重的伤害——总有一个很好的学习机会,而不是一个门外汉。学习新事物(几乎)从来都不是一个坏主意:)啊,这看起来是一本非常有趣的书。不幸的是,我的目标是XP以上的32位和64位平台,无法使用它。真可惜。不过,谢谢你把它指给我看!UMS解决了Miky Dinescu在回答中强调的问题。至于“为什么”部分,我不记得我最初发布问题时的确切情景,但总的来说,我正在寻找一种方法来确保我的应用程序(我正在制作一个简单的游戏引擎)尽可能经常地获得调度程序的一些注意,最好是在每个时间片中。我想让它尽可能平滑,并有一个预算,每帧处理时间为16.67ms,屏幕刷新率为60Hz。一个简单的测试证明我的线程可以被抢占超过10毫秒。我想我不得不接受这样一个事实:如果我想对操作系统好一点,可能会跳过一个框架。至于“PPL”和“AAL”-它们看起来很有趣,谢谢你给我看。我