系统调用时上下文调度
系统调用时上下文调度
CPU 的特权等级:
linux 中只使用了 Ring 0
和 Ring3
在系统调用时可能会发生上下文切换,但这取决于具体情况。系统调用涉及从用户态(User Mode)切换到内核态(Kernel Mode),这是一个模式切换,不一定总是伴随完整的进程上下文切换。让我们更详细地看一下:
1) 用户态和内核态切换(模式切换)
当一个进程执行系统调用时,CPU 会从用户态切换到内核态,以便操作系统内核执行需要访问硬件资源或特权操作的指令(如文件读写、内存管理等)。这叫做模式切换。
- 模式切换 ≠ 上下文切换:
模式切换是 CPU 从执行用户代码切换到执行内核代码,并不涉及进程的完整上下文(如寄存器、页表、内存等)切换,因此它比完整的上下文切换开销要小。
2) 系统调用时的上下文切换
在以下几种情况下,系统调用会导致真正的进程上下文切换:
-
进程阻塞:
如果系统调用需要等待某些事件(如 I/O 操作、网络请求、锁等),当前进程会被挂起,进入等待状态。此时,操作系统会进行进程上下文切换,将 CPU 资源分配给其他进程执行,直到当前进程的请求完成,再切换回该进程继续执行。例如:
- 调用
read()
时,如果数据还没有准备好,进程会进入阻塞状态,等待 I/O 完成,导致上下文切换。
- 调用
-
时间片用完:
如果系统调用时间过长,进程在内核态执行时,可能会因为时间片耗尽被操作系统调度器切换出去,调度其他进程。这样会产生上下文切换。 -
高优先级进程的出现:
当进程在系统调用中运行时,如果有更高优先级的进程进入可运行队列,操作系统可能强制进行上下文切换,将 CPU 资源让给更高优先级的进程。
3) 不会导致上下文切换的系统调用
某些系统调用不会导致上下文切换,比如短时间内能立即完成的调用。典型的例子包括:
getpid()
:返回进程的 PID,几乎是瞬时操作。gettimeofday()
:获取当前时间,操作非常快。
这些系统调用通常只涉及模式切换(从用户态切换到内核态再返回),不会导致进程切换。
4) 总结
系统调用时不一定会发生上下文切换:
- 如果系统调用涉及 I/O 操作或进程需要等待某些资源时,系统会发生进程上下文切换。
- 仅涉及用户态和内核态的模式切换时,不涉及完整的上下文切换,开销较小。
5) 参考
- 操作系统之哲学原理第2版 - 3.3 内核态和用户态 - 邹恒明 - 微信读书: https://weread.qq.com/web/reader/9eb326d05933d79ebf22eb3k6ea321b021d6ea9ab1ba605
- 现代操作系统(原书第4版) (豆瓣): https://book.douban.com/subject/27096665/
本站总访问量次 本站访客数人次 本文总阅读量次