我的线程可以帮助操作系统决定何时将其上下文切换吗?
我正在 Linux 上用 C++ 开发一个线程应用程序,它试图实现实时,根据心跳执行操作,或者尽可能接近实时。
在实践中,我发现操作系统正在交换我的线程,并导致切换时延迟长达十分之一秒,从而导致心跳不规则。
有没有一种方法可以让我的线程向操作系统暗示现在是上下文切换的好时机?我可以在进行心跳后立即进行此调用,从而最大限度地减少由于不合时宜的上下文切换而导致的延迟。
I am working on a threaded application on Linux in C++ which attempts to be real time, doing an action on a heartbeat, or as close to it as possible.
In practice, I find the OS is swapping out my thread and causing delays of up to a tenth of a second while it is switched out, causing the heartbeat to be irregular.
Is there a way my thread can hint to the OS that now is a good time to context switch it out? I could make this call right after doing a heartbeat, and thus minimize the delay due to an ill timed context switch.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
很难说您的情况的主要问题是什么,但它肯定不是可以通过调用 sched_yield() 或 pthread_yield() 来纠正的问题。在 Linux 中,yield 唯一明确定义的用途是允许不同的就绪线程在 SCHED_FIFO 调度策略下,在同一 CPU 上以相同优先级抢占当前 CPU 绑定的正在运行的线程。几乎在所有情况下这都是一个糟糕的设计决策。
如果您认真对待 Linux 中“尝试实时”的目标,那么首先,您应该使用实时
sched_setscheduler
设置(SCHED_FIFO 或 SCHED_RR,优先使用 FIFO) 。其次,获取 Linux 的完整抢占补丁(来自 kernel.org如果您的发行版不提供,它还使您能够重新安排设备驱动程序线程并执行高于硬盘或以太网驱动程序线程的线程。
第三,请参阅 RTWiki 和其他资源,了解有关如何设计和设置的更多提示实时应用程序。
无论任何像样的桌面系统上的系统负载如何,这都足以让您的响应时间低于 10 微秒。我有一个嵌入式系统,在磁盘/系统负载较重的情况下,我只挤出了 60 us 的响应空闲时间和 150 us 的响应时间,但它仍然比您所描述的快几个数量级。
It is hard to say what the main problem is in your case, but it is most certainly not something that can be corrected with a call to
sched_yield()
orpthread_yield()
. The only well-defined use for yielding, in Linux, is to allow a different ready thread to preempt the currently CPU-bound running thread at the same priority on the same CPU under SCHED_FIFO scheduling policy. Which is a poor design decision in almost all cases.If you're serious about your goal of "attempting to be real-time" in Linux, then first of all, you should be using a real-time
sched_setscheduler
setting (SCHED_FIFO or SCHED_RR, FIFO preferred).Second, get the full preemption patch for Linux (from kernel.org if your distro does not supply one. It will also give you the ability to reschedule device driver threads and to execute your thread higher than, say, hard disk or ethernet driver threads.
Third, see RTWiki and other resources for more hints on how to design and set up a real-time application.
This should be enough to get you under 10 microseconds response time, regardless of system load on any decent desktop system. I have an embedded system where I only squeeze out 60 us response idle and 150 us under heavy disk/system load, but it's still orders of magnitude faster than what you're describing.
您可以使用各种命令告诉当前正在执行的线程暂停执行,例如 产量。
仅仅告诉线程暂停是非确定性的,999 次它可能提供良好的间隔,而 1 次则不能。
您可能需要查看实时调度以获得一致的结果。本网站 http://www2.net.in.tum .de/~gregor/docs/pthread-scheduling.html 似乎是研究线程调度的一个很好的起点。
You can tell the current executing thread to pause execution with various commands such as yield.
Just telling the thread to pause is non-determanistic, 999 times it might provide good intervals and 1 time it doesn't.
You'll will probably want to look at real time scheduling for consistant results. This site http://www2.net.in.tum.de/~gregor/docs/pthread-scheduling.html seems to be a good starting spot for researching about thread scheduling.
使用
sched_yield
和毛皮线程有一个
pthread_yield
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_yield.3.htmluse
sched_yield
And fur threads there is an
pthread_yield
http://www.kernel.org/doc/man-pages/online/pages/man3/pthread_yield.3.html我对这个问题有点困惑。如果您的程序只是等待周期性的心跳然后做一些工作,那么当您返回等待心跳时,操作系统应该知道安排其他事情。
你不会为了得到你的“心跳”而在旗帜上旋转吧?
I'm a bit confused by the question. If your program is just waiting on a periodic heartbeat and then doing some work, then the OS should know to schedule other things when you go back to waiting on the heartbeat.
You aren't spinning on a flag to get your "heartbeat" are you?
您正在使用诸如
setitimer()
之类的计时器函数,对吧? 对???如果不是,那么你就完全错了。
您可能需要指定一个比您真正需要的稍短的计时器间隔。如果您使用实时调度程序优先级和计时器,您的进程几乎总是会按时唤醒。
我想说总是准时,但 Linux 还不是一个完美的实时操作系统。
You are using a timer function such as
setitimer()
, right? RIGHT???If not, then you are doing it all wrong.
You may need to specify a timer interval that is just a little shorter than what you really need. If you are using a real-time scheduler priority and a timer, your process will almost always be woken up on time.
I would say always on time, but Linux isn't a perfect real-time OS yet.
我对 Linux 不太确定,但在 Windows 上,有人解释说 您由于多种原因,无法要求系统不打扰您(主要是第一段)。在我看来,原因之一是硬件中断随时可能发生,而且您无法控制。
编辑 有人刚刚建议使用
sched_yield
然后删除了他的答案。不过,它会为您的整个过程节省时间。您还可以使用sched_setscheduler
来提示内核什么你需要。I'm not too sure for Linux, but on Windows it's been explained that you can't ask the system to not interrupt you for several reasons (first paragraph mostly). Off my head, one of the reasons is hardware interrupts that can occur at any time and over which you have no control.
EDIT Some guy just suggested the use of
sched_yield
then deleted his answer. It'll relinquish time for your whole process though. You can also usesched_setscheduler
to hint the kernel about what you need.