系统调用和上下文切换

60

非常抱歉,我要问这个问题时已经被问过了,但我无法从他们那里得到清晰的答案。因此,我提出以下相关问题,以便了解系统调用(模式切换)和上下文切换之间的区别

  • 为什么说系统调用不需要上下文切换,当调用进程的上下文必须被保存然后重新加载。这只是因为根据上下文切换的定义,必须切换到另一个进程吗?

  • 什么意思是当进行系统调用时内核会在“用户上下文”中执行。

  • 根据维基百科文章:http://en.wikipedia.org/wiki/Context_switch

虽然对于系统调用而言通常不需要上下文切换,但这取决于操作系统,在系统调用期间可能会发生上下文切换。 我想知道如果在系统调用时发生上下文切换会发生什么。有没有例子?

2个回答

102
你需要了解一个线程/进程上下文有多个部分,一个与执行直接相关并保存在CPU和一些系统表中的内存中供CPU使用(例如页面表),另一个则是操作系统所需的,用于簿记(考虑各种ID、句柄、特殊的操作系统特定权限、网络连接等)。
完整的上下文切换涉及交换这两者,旧的当前线程/进程消失一段时间,新的当前线程/进程进入一段时间。这就是线程/进程调度的本质。
现在,系统调用在相互之间非常不同。
考虑一些简单的东西,例如请求当前日期和时间的系统调用。CPU从用户模式切换到内核模式,保留用户模式寄存器值,执行一些内核代码以获取必要的数据,在调用者可以访问的内存或寄存器中存储它,恢复用户模式寄存器值并返回。这里没有太多的上下文切换,只有在模式之间转换所需的内容,用户和内核。
现在考虑一种涉及阻塞调用者直到某个事件或数据可用的系统调用。操纵互斥量和读取文件将是此类系统调用的示例。在这种情况下,内核被迫保存调用者的完整上下文,将其标记为阻塞,因此调度程序无法运行它,直到该事件或数据到达,并加载另一个准备好的线程/进程的上下文,以便它可以运行。
这就是系统调用与上下文切换的关系。
内核在用户或进程的上下文中执行意味着每当内核代表某个进程或用户进行工作时,它都必须考虑该用户/进程的上下文,例如当前进程/线程/用户ID、当前目录、区域设置、各种资源(例如文件)的访问权限等,所有这些东西在不同的进程/线程/用户之间可能是不同的。如果进程有独立的地址空间,那么这个地址空间也是进程上下文的一部分。因此,当内核需要访问进程的内存(读写文件数据或网络数据包)时,它必须能够访问进程的地址空间,也就是说,它必须在进程的上下文中(然而并不意味着内核必须加载整个上下文才能访问特定的地址空间中的内存)。
这对你有帮助吗?

4
很棒的解释!谢谢!!肯定很有帮助 :) - vjain27
1
谢谢您的清晰解释。我还有一个问题不太明白。如果即将到来的进程页面已经被换出,那么将它们(页面)换回内存也会产生成本,对吗? - stdout
1
如果我没记错的话,在x86上原则上可以有用户模式任务来处理中断和异常(查找任务状态段任务门)。其他一些CPU可能支持类似的方案。但是,最常见的是在内核中完全或部分地处理中断(系统部分)。无论如何,如果您有问题,请提出一个新问题。如果您想讨论这些东西,可以去alt.os.development和osdev.org。 - Alexey Frunze
1
@AlexeyFrunze 那么在非阻塞系统调用的情况下,就没有上下文切换了对吧? - Zephyr
1
@Zephyr 这个问题不应该存在,或者与非阻塞系统调用无关或透明。 - Alexey Frunze
显示剩余13条评论

-6

当用户只想访问仅适用于内核模式的内容时,模式切换会发生。


12
这篇读起来像是一个平庸的评论,而不像是一个回答。请在回答问题时认真花点时间——而不是仅仅倒出一句没有标点符号的想法,并且完全没有试图使其对读者有所帮助。 - GhostCat

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接