抢占和上下文切换的区别

Posted

技术标签:

【中文标题】抢占和上下文切换的区别【英文标题】:difference between Preemption and context switch 【发布时间】:2012-07-21 02:10:22 【问题描述】:

一个小介绍,

我目前正在编写一个小型(读取微小的)RTOS 内核,它应该与内核中的大多数内容是一体的。但是我在下面列出的一些事情上找不到太多信息,这会很有帮助,除此之外,它实际上不是某种大学项目,而是我按照自己的意愿做的事情。

回答所有问题的更好选择是,如果您可以向我推荐一个免费提供的 RTOS(甚至是一本免费书籍),最好是用于 arm ,它实现了用户空间并且是可抢占的(但并不复杂像Linux)。 Linux 有一些迄今为止我见过的最糟糕的文档(我确实尝试从 linux 代码中找出问题,但是只有大量的定义分散在百万个文件和函数挂钩中,名称很奇怪,而且每个版本都被重命名了有时会移动...)

    “抢占”和“上下文切换”有什么区别?

    抢占式和非抢占式内核之间的主要区别是什么?程序员需要做哪些工作才能使内核抢占式?

    如何创建和使用用户模式?

    ARM 文档说,在用户模式下,任何切换到特权模式的指令都将被视为未定义指令。

    如果是这样,用户空间程序使用内核代码的唯一方法是系统调用吗?

    那么内核如何响应或与用户空间交互?

    这是否意味着启动后的唯一内核线程(在简单系统中)将是空闲线程?

    如果内核代码和数据所在的页面在切换到用户进程时未映射,那么在系统调用或中断时,内核代码如何在不映射到虚拟地址空间的情况下执行?

    “可抢占内核”是否仅意味着内核的设计方式是在内核代码执行期间进行上下文切换是安全的?还是需要做更多的工作?

哦,如果这里不允许这样多个问题,抱歉,找不到任何相关信息。

【问题讨论】:

来自faq:“你的问题应该有合理的范围。如果你能想象一本书可以回答你的问题,那你就问得太多了。”这里的问题太多了,而且范围真的很广。看起来你需要一本关于操作系统设计的好书,尤其是关于 ARM 的一本好书。 是的,如问题中所述,一本书将是一件好事。问题的范围本身并不是那么广泛,它们要么是关于抢占,要么是关于内核用户的关系。但是,我担心它们对于单个帖子来说太多了,对此感到抱歉。我会看看 mod 建议将其分解或将其更改为“需要一本好的 arm 系统设计书”之类的内容。.. 图书推荐问题在这里不起作用。 (有一些历史悠久的,但不欢迎新的。) 我很乐意以任何形式获得我的答案,无论是指向与我一样古老的线程的链接、指向书籍的链接、此处的长答案、指向某些源代码的链接好的(免费)软件等。但是,如果我确实需要推荐一本好的系统设计书(虽然我只是在寻找一些答案,但好好阅读不会有什么坏处),我在哪里发布呢?这是我能想到的最相关的堆栈站点。 Stack Exchange 网站通常是问答,而不是推荐引擎。 【参考方案1】:

我的印象是 uC/OS-III 不是免费的,而是许可的。

FreeRTOS (http://www.freertos.org/) 是一个很棒的免费 RTOS,并且解释得很好。

你一定要去那里看看

【讨论】:

uC/OS 在商业产品中不能免费许可,而且从来没有。各种产品/产品线/cpu/站点licenses 的定价(据我所知)从 1 万美元到 2 万美元不等。然而,它一直都是可用的源代码,而且这本书很棒(是的,我认为它比 FreeRTOS 有更好的文档记录); Jean Labrosse 非常注重教育和开放性。 建议的编辑已被拒绝:***.com/suggested-edits/327885 @KevinVermeer - 这是一个非常极端的编辑,它确实改变了答案的含义,所以我明白为什么人们拒绝它。我的建议是将其发布为全新的答案或将其附加到您接受的答案中。看起来不错的材料,但我们确实尽量尊重原作者的意图。 @BradLarson - 感谢您的参与。我意识到它增加了很多,但我没有添加新信息。我正在澄清作者的意图:用来自源站点的证据支持和澄清模糊的“印象”,将纯文本链接更改为指向大型站点有用部分的正确格式的链接,并引用有关的相关文章建议的 RTOS 的优点。 @KevinVermeer - 一开始的语气有细微的变化,你确实添加了很多新信息。过去,我们曾有人抱怨编辑对他们的答案进行了太多修改,因此我仍然认为最好的解决方案是根据您的编辑编写自己的答案(也许会说“扩展根据拉斐尔在回答中所说的话……”)。对一个问题有多个答案没有问题。【参考方案2】:

我不会回答您列举的每个问题,而是尽我所能满足您(谢天谢地)加粗的请求:

如果您可以向我推荐一本免费提供的用于 arm 的 RTOS(甚至是免费书籍),更好的选择是回答所有问题

Micrium 的 uC/OS-III 是一个基于优先级的实时内核,(当然)支持同步和异步抢占。而且,幸运的是(以及我回复的原因)是有一本免费的书可用,而且源代码也可用。

前往main page for uC/OS-III,在左侧您将看到一个视频链接,该视频讨论了源代码可用性(“uC/OS-III 源代码可用”)。

就书籍而言,转到projects page,然后选择与您的目标最匹配的书籍。 90%的材料是一样​​的;只有特定于 CPU 的内容(如上下文切换、中断和初始化)会因书而异。

你必须注册才能下载这本书和代码,这对我来说似乎很公平。

祝你好运,玩得开心。感谢您用粗体表示您的最终要求/目标,这让这变得容易多了。

【讨论】:

谢谢,我也会调查的。【参考方案3】:

正如 Mat 所写,这可能是不合理的范围。不过,我将尽可能多地关注问题的总和,就像关注一个范围合理的问题一样,希望这将有助于您开始研究。

1 “抢占”和“上下文切换”有什么区别?

抢占是在不涉及进程的情况下中断进程的行为。在这种情况下,这可能意味着将触发定时器中断。这个词来自preemption 的法律概念:在他人之前或优先于他人主张或购买的行为或权利。 就您的目的而言,这意味着当定时器中断触发时,中断服务例程 (ISR) 优先于之前运行的代码。这根本不需要涉及内核。您可以让代码在任何 ISR 中运行,这些 ISR 将抢先运行。

当操作系统代码(抢占式运行)在一个进程或线程的上下文与另一个之间改变处理器的状态(寄存器、模式和堆栈)时,就会发生上下文切换。处理器的状态可能在一个线程中的某一行代码。它将在寄存器中具有临时数据、位于某个内存区域的堆栈指针以及其他状态信息。抢占式操作系统可以存储此状态(存储到静态内存或进程堆栈中)并加载前一个进程的状态。这称为上下文切换。

2 抢占式内核和非抢占式内核之间的主要区别是什么?程序员需要做哪些工作才能使内核抢占式?

在抢占式内核中,可以在任意两条汇编指令(称为“序列点”)之间触发中断。在非抢占式内核中,正在运行的进程必须调用yield() 函数以允许其他线程运行。抢占式内核更复杂,但提供了更好的并发错觉。使用setjmp.h 可以非常简单地完成非抢占内核,但每个线程必须定期调用yield() 否则其他线程将无法运行。

当像yield() 这样的函数被调用时,处理器的状态会被自动存储。当您想让您的操作系统抢占式时,您必须手动存储此信息。

3 如何创建和使用用户模式?

ARM 文档说,在用户模式下,任何切换到特权模式的指令都将被视为未定义指令。

正确。但是,他们还说任何中断都会自动以特权模式运行。在 ARM 系统上,您可以使用svc 指令来生成软件中断。 SVC 代码(您的操作系统的一部分)将能够在特权模式下运行。

4 如果是这样,用户空间程序使用内核代码的唯一方法是系统调用?

正确。至少,这是唯一安全或正确的方法。

5 那么内核如何响应或与用户空间交互?

在 ARM 上,SVC 指令可以获得 8 位值。这可用于生成 256 个系统调用,例如 yield、启用中断、禁用中断或任何您需要的。如果需要,您还可以选择创建共享内存或消息传递交互机制。

6 这是否意味着启动后(在简单系统中)唯一的内核线程将是空闲线程?

这完全取决于您如何设计系统。如果您选择仅在创建所有线程后启动内核,这可能会更简单——这样您就不必担心动态分配线程。或者,您可以从空闲线程开始,稍后再添加其他线程(通过远程外壳?我认为您希望至少有一个用户线程始终如一地运行......)

7 如果内核代码和数据所在的Page在切换到用户进程时未映射,那么在系统调用或中断时,内核代码如何在不映射到虚拟地址空间的情况下执行?

就像内核模式代码在特权模式下运行一样,即使代码之前在用户模式下执行,内核模式代码也会从主堆栈指针 (MSP) 运行,即使进程代码使用不同的地址空间也是如此。

8 “可抢占内核”是否仅意味着内核的设计方式是在内核代码执行期间进行上下文切换是安全的?还是需要做更多的工作?

我认为这意味着内核可以抢占用户代码,而不是内核本身可以被抢占。中断内核的任何事情都是困难和不寻常的。这将需要更多的工作,而我正在努力了解您为什么想要它。

【讨论】:

内核抢占非常重要(我敢打赌,尤其是对于实时系统)。 linuxjournal.com/article/5600 令人满意的答案但是我还是不明白 在7中,我问如果内核代码没有映射到虚拟空间中,cpu如何从那里获取代码?这不应该导致数据中止吗? 8,由于这是一个单片内核,我在内核中实现了“大多数”的东西,所以这需要我实际使内核代码抢先,假设我得到一个自旋锁获取系统调用或一些内核线程在单个 CPU 上调用它, 会导致死锁,但如果该线程被抢占,它会在任何系统上运行良好,因为线程会在用完所有量子后被弹出。 @user1075375 - 7 - 不,这不会导致数据中止,因为 CPU 正在特权模式下运行。至少,我是这么理解的——我承认我的大部分工作都是在没有 MMU 或虚拟内存的系统上完成的。 Re 8 - 如果您有多个 CPU,那么是的,如果内核代码是可抢占的,那将会很有用。但是,您无法从当前 CPU 获得自旋锁获取系统调用 - 当内核代码运行时,用户代码未运行。 @Mat - 啊,我明白了 - 你基本上是在同时运行另一个内核和你的抢占式内核。有趣! 我已经投了赞成票但是如果有更好的答案,我会再等一段时间,谢谢你的时间。

以上是关于抢占和上下文切换的区别的主要内容,如果未能解决你的问题,请参考以下文章

linux 2.6调度和抢占 - preempt_count使用

Linux操作系统进程优先级和进程切换

进程上下文

1.2. 上下文切换:__schedule()

1.2. 上下文切换:__schedule()

进程与线程的切换比较