C++ 如何在短时间内关闭操作系统中切换线程的中断,以完成关键部分的代码?

C++ 如何在短时间内关闭操作系统中切换线程的中断,以完成关键部分的代码?,c++,c,multithreading,winapi,posix,C++,C,Multithreading,Winapi,Posix,众所周知,如果执行线程的数量大于处理器核的数量,则线程在特定的时隙(量子)在它们之间切换。这对于Win/*nix来说是正确的。但是,线程切换的实现机制是什么,它是在特定时间段启动的硬件中断,不是吗 这个中断(IRQ)的数目是多少,我可以更改/设置这个时间(时隙)的值吗?对于我的代码中对性能(实时)至关重要的部分(通过使用WINAPI/Posix),我如何在短时间内关闭这个中断 更详细的回答:如果你有一个关键任务,你可以尝试提高该线程的优先级,但这不会无限期地起作用,因为现代(非实时)操作系统不允

众所周知,如果执行线程的数量大于处理器核的数量,则线程在特定的时隙(量子)在它们之间切换。这对于Win/*nix来说是正确的。但是,线程切换的实现机制是什么,它是在特定时间段启动的硬件中断,不是吗


这个中断(IRQ)的数目是多少,我可以更改/设置这个时间(时隙)的值吗?对于我的代码中对性能(实时)至关重要的部分(通过使用WINAPI/Posix),我如何在短时间内关闭这个中断

更详细的回答:如果你有一个关键任务,你可以尝试提高该线程的优先级,但这不会无限期地起作用,因为现代(非实时)操作系统不允许线程“占用机器中的所有CPU”

此外,任何中断都可能导致您的任务被安排。计时器是基于时间量执行此操作的计时器,但例如,如果另一个任务正在等待网络数据包,则当数据包到达时,该任务将被放入可运行队列中,因此调度程序将在该点运行,并决定是否运行另一个线程(从技术上讲,它既不是您的线程,也不是网络数据包等待线程)。同样,如果您的线程接触到一些已交换到磁盘的内存,则显然在从磁盘读回数据之前,它无法继续,因此它将被“停驻”在阻塞队列和可运行队列中的其他线程中。当从磁盘读取该块时,操作系统将再次重新调度


解决这个问题真的没有(简单的)方法。任何不容易的方法都会涉及到弄乱驱动程序和几乎编写自己的操作系统。

你不能关闭操作系统的计时器中断;它们是 在操作系统本身内进行管理,并且是正确运行所必需的 功能。在大多数Unix下,您可以使用
sched\u setscheduler
和/或
pthread_setscheduler
将调度策略设置为
SCHED_FIFO
SCHED_setparam
/
pthread_setschedprio
设置 优先级;然后将保证不会中断您 除非它有更高的优先级

至少在Linux下(以及我工作过的其他Unix下), 也可以将页面锁定到实际内存中,因此您无法 获取页面错误(这将导致您等待 磁盘访问)。Linux中的功能是
mlock

请注意,您可能需要特殊权限才能更改
全局调度程序或使用
mlock

如果需要确定性调度,则需要实时操作系统


“如何关闭此中断?”-我可能错了,但这听起来是一个非常糟糕的主意…只使用POSIX功能,你不能。此外,在用户空间程序中切换中断从来都不是一个好主意,在驱动程序中也很少。在大多数健全的操作系统中,你根本不能这样做,除非你是在内核代码中运行。你实际上想实现什么?你想要你的thr吗ead占用CPU?如果是这样的话,给它一个更高的优先级。如果他说的是实时,问题可能是延迟。他收到了一个请求,并且必须在固定的最长时间内响应。这意味着1)他的系统必须使用确定性调度策略,2)他的进程必须具有足够高的优先级,以确保抢占任何其他内容,3)它使用的任何内存页都必须锁定在内存中。“现代操作系统不允许线程占用机器中的所有CPU”:Unix当然可以,至少在实时选项上是这样,我敢打赌,所有像VxWorks这样的实时操作系统也可以。如果你想做任何实时处理,它或多或少是必不可少的。@ JAMESKANZE:添加了“非实时”。我不认为Linux是一个实时操作系统(Office)。但是,允许使用调度器和改变优先级的功能被POSIX视为“实时”扩展。将不允许单个线程无限期地运行-至少它肯定不允许关闭中断。手册页上并没有这样说:“SCHED_FIFO进程运行,直到它被I/O请求阻塞,被更高优先级的进程抢占,或者调用SCHED_yield(2)。”如果您将
SCHED_FIFO
设置为99(Linux下的最高优先级),不执行任何IO,也不调用
SCHED_yield
,您可以永远使用100%的CPU。(当然,要做到这一点,你必须是一个有特权的用户。)大多数现代Unice都实现Posix的实时扩展,正确使用Posix可以产生确定性的调度。(我知道Solaris有,Linux的手册页也说明了这点。)当然,但这是操作系统中托管的不同操作系统,因为您无法访问这些扩展中的完整操作系统功能。我不太了解Posix,我只对Windows使用了一个类似的扩展(一个商业扩展):当然可以。它们只是Posix不需要的附加函数。什么也没拿出来,谢谢!将
SCHED_FIFO
和优先级设置为99,不要调用
SCHED_yield
,使用固定内存并将
/proc/irq//smp_affinity
所有IO irq设置为同一个CPU核心-可以为我提供100%的其他CPU核心。但这是给我的。也许,我可以自己调用soft IRQ,并在(soft IRQ)中断的代码中执行我代码中的性能关键部分吗?