【OSTEP】多道程序和时分共享 | 虚拟地址空间 | 用户栈vs内核栈 | 进程结构: struct thread | 虚拟vs物理地址空间 | 地址转换方案

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介: 【OSTEP】多道程序和时分共享 | 虚拟地址空间 | 用户栈vs内核栈 | 进程结构: struct thread | 虚拟vs物理地址空间 | 地址转换方案

💭 写在前面:

本系列博客为复习操作系统导论的笔记,内容主要参考自:

  • Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy PiecesA. Silberschatz, P. Galvin, and G. Gagne,
  • Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7.Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .



0x00  早期操作系统(OS in The Early System)

Load only one process in memory.(只在内存中运行一个进程)

  • Poor utilization and efficiency (利用率低,效率差)

0x01  多道程序和时分共享(Multi-programming and Multi-tasking)

Multi-programming(多道程序)

  • Load multiple processes in memory.
  • Execute one for a short while and switch processes between them in memory.
  • Increase utilization and efficiency.

Time-sharing (multitasking)(时分共享)

Logical extension in which CPU switches jobs so frequently that users can interact with each job while it is running, creating interactive computing.

Cause an important protection issue(保护问题)

  • Errant memory accesses from other processes. (来自其他进程的错误内存访问)
  • 多个程序同时驻留在内存中,保护就成了重要问题。人们不希望一个进程可以读取其他进程的内存,更别说修改了。

0x02  进程地址空间(Process Address Space)

OS creates an abstraction of physical memory. (OS创造一个物理内存抽象

Contains all about a running process.  (包罗所有正在运行的进程)

Consists of program code, heap, stack, etc. (由程序代码、堆、栈组成)

  • Code : Where instructions live.
  • Heap : Dynamically allocate memory.
  • Stack : Store return addresses or values; Contain local variables and arguments to routines

(为了便于讲解,我们假设只有这三个部分)

0x03  虚拟地址空间(Virtual Address Space)

都是假象!凉凉月色为你思念成河,化作春泥呵护着我……

Every address in a running program is virtual. (程序运行时你看到的所有地址都是虚拟的)

  • OS translates the virtual address to physical address

例子:下面是一个打印内存地址的简单程序:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
  printf("location of code : %p\n", (void*)main);
  printf("location of heap : %p\n", (void*)malloc(1));
  int x = 3;
  printf("location of stack : %p\n", (void*)&x);
  return x;
}

🚩 运行结果如下:(在64位Linux环境下跑的)

💡 由此可见:代码在地址空间开头,然后是堆,而栈在这个大型虚拟地址空间的另一端。所有的这些地址都是虚拟的,是假的!纯纯的 fake!都是特喵的骗人的!并且将由操作系统和硬件翻译成物理地址,以便从真实的地理位置获取该地址的值。

0x04  内核是个什么玩意(What About Kernel)

Each OS process has its own virtual address space and part of each virtual address space is reserved for the kernel.

(每个操作系统都有自己的虚拟地址空间,并且每个虚拟地址都是要留一部分空间给内核的)

  • The size is configurable (e.g., 1G out of 4G).

When a process traps into the kernel, kernel uses the mapped space reserved for the kernel. (当一个进程陷阱进入内核时,内核使用为保留给内核的映射空间)

Although the kernel uses virtual address mapping, most of the kernel memory is mapped linearly onto physical addresses

(尽管内核使用内存地址映射,但 绝大多数内核的内存还是以线性地方式映射到物理地址上的

0x05  用户栈 VS 内核栈(User Stack vs Kernel Stack)

In general, two types of stacks are used to run application programs.(一般来说,有两种类型的栈被用来运行应用程序):

  • When they run in user mode, the user stack is used. (当它们在用户模式下运行时,使用的是用户栈)
  • When they run in kernel mode (via system call), the kernel stack is used. (当它们在内核模式下运行时 (通过系统调用),使用的是内核栈)

When application programs invoke a system call(当应用程序调用一个系统调用时):

  • Enters the kernel via trap (interrupt).  (通过陷阱(中断)进入内核
  • Switch from user stack to kernel stack. (从用户栈切换到内核栈
  • In Pintos, kernel stack is allocated 4KB away from the start of PCB (Limited – do not allocate big static variables inside functions).

Raise the privilege level(提高权限级别)

0x06  进程结构: struct thread(Process Structure)

💬 代码:pintos/src/threads/thread.h

struct thread
{
  /* Owned by thread.c. */
  tid_t tid;                       /* Thread identifier. */
  enum thread_status status;       /* Thread state. */
  char name[16];                   /* Name (for debugging purposes). */
  uint8_t* stack;                  /* Saved (kernel) stack pointer. */
  int priority;                    /* Priority. */
  struct list_elem allelem;        /* List element for all threads list. */
    /* Shared between thread.c and synch.c. */
  struct list_elem elem;           /* List element. */
#ifdef USERPROG
/* Owned by userprog/process.c. */
  uint32_t* pagedir; /* Page directory. */
#endif
/* Owned by thread.c. */
  unsigned magic;                  /* Detects stack overflow. */
};

🔍 status:

0x07  逻辑(虚拟)VS 物理地址空间(Logical (Virtual) vs. Physical Address Space)

The user program deals withlogical (virtual) addresses, it never sees the real physical addresses.   用户程序处理的是 逻辑(虚拟)地址,它永远不会看到真正的物理地址

  • Logical address(逻辑地址):由 CPU 生成,也被称为虚拟地址。
  • Physical address(物理地址):内存单元看到的地址。

The concept of a logical address space that is bound to a separate physical address space (i.e., mapping between logical address space and physical address space) is central to proper memory virtualization.  绑定到独立物理地址空间的逻辑地址空间 (即逻辑地址空间和物理地址空间之间的映射) 的概念是正确的内存虚拟化的核心

The run-time mapping from virtual to physical addresses is done by a hardware device called the memory management unit (MMU) .

从虚拟地址到物理地址的运行时映射是由一个称为内存管理单元(MMU)的硬件设备完成的。

0x08  虚拟内存与物理内存之间的映射: 简单概述(Mapping Between Virtual to Physical Memory: Simple Overview)

  • Divide logical (virtual) memory into blocks of same size called pages (size is power of 2, between 512 bytes and 8192 bytes) .   将逻辑(虚拟)内存分为相同大小的块,称为页(大小是2的幂,在512字节和8192字节之间)。
  • Divide physical memory into fixed-sized blocks called frames.  将物理内存划分为固定大小的块,称为 frames。
  • Page and frame size are usually the same.  页和帧的大小通常是一样的。  
  • Keep track of all free frames.  追踪所有空闲的框架。
  • To run a program of size n pages, we need to find m free frames (m can be smaller than n; partially load -> virtual memory). 为了运行一个 页大小的程序,我们需要找到 个空闲的帧( 可以比 小,部分加载 → 虚拟内存)。
  • Each process sets up a page table to translate logical to physical addresses.  每个进程都设置了一个页表,将逻辑地址转换为物理地址。

0x09  地址转换方案: 简单概述(Address Translation Scheme: Simple Overview)

由CPU产生的地址被分为:

  • Page number (p) – used as an index into a page table which contains base address of each page in physical memory.
  • Page offset (d) – combined with base address to define the physical memory address that is sent to the memory unit.

📌 [ 笔者 ]   王亦优
📃 [ 更新 ]   2022.10.4
❌ [ 勘误 ]   /* 暂无 */
📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
              本人也很想知道这些错误,恳望读者批评指正!

📜 参考资料 

Remzi H. Arpaci-Dusseau and Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces

A. Silberschatz, P. Galvin, and G. Gagne,

Operating System Concepts, 9th Edition, John Wiley & Sons, Inc., 2014, ISBN 978-1-118-09375-7.

Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

百度百科[EB/OL]. []. https://baike.baidu.com/.

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
3月前
|
网络协议 Linux
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
Linux查看端口监听情况,以及Linux查看某个端口对应的进程号和程序
595 2
|
3月前
|
Linux Python
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
linux上根据运行程序的进程号,查看程序所在的绝对路径。linux查看进程启动的时间
64 2
|
1月前
|
安全 API C#
C# 如何让程序后台进程不被Windows任务管理器强制结束
C# 如何让程序后台进程不被Windows任务管理器强制结束
58 0
|
2月前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【9月更文挑战第13天】在编程的世界中,进程间通信(IPC)如同一场精彩的社交舞会,每个进程通过优雅的IPC机制交换信息,协同工作。本文将带你探索Python中的IPC奥秘,了解它是如何让程序实现无缝信息交流的。IPC如同隐形桥梁,连接各进程,使其跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存及套接字,适用于不同场景。通过一个简单的队列示例,我们将展示如何使用`multiprocessing.Queue`实现进程间通信,使程序如同社交达人般高效互动。掌握IPC,让你的程序在编程舞台上大放异彩。
22 3
|
3月前
|
数据采集 监控 API
如何监控一个程序的运行情况,然后视情况将进程杀死并重启
这篇文章介绍了如何使用Python的psutil和subprocess库监控程序运行情况,并在程序异常时自动重启,包括多进程通信和使用日志文件进行断点重续的方法。
|
3月前
|
Python
惊!Python进程间通信IPC,让你的程序秒变社交达人,信息畅通无阻
【8月更文挑战第1天】在编程世界中,进程间通信(IPC)犹如一场社交舞会,各进程通过IPC机制优雅地交换信息,共同完成复杂任务。IPC就像隐形桥梁,连接并行运行的进程,使它们能跨越边界自由沟通。Python提供了多种IPC机制,如管道、队列、共享内存和套接字等,适应不同需求。例如,使用`multiprocessing.Queue`实现进程间通信,生产者向队列添加数据,消费者取出并处理数据,两者虽独立却能有效协作。IPC打破了进程界限,使得程序能像社交达人般自由交流,构建出高效、灵活的应用。掌握IPC,让程序信息畅通无阻。
25 1
|
3月前
|
并行计算 开发者 Python
解锁Python多进程编程的超能力:并行计算的魔法与奇迹,探索处理器核心的秘密,让程序性能飞跃!
【8月更文挑战第12天】在Python编程领域,多进程编程是一项关键技能,能有效提升程序效率。本文通过理论与实践结合,深入浅出地介绍了Python中的多进程编程。首先解释了多进程的概念:即操作系统中能够并发执行的多个独立单元,进而提高整体性能。接着重点介绍了`multiprocessing`模块,演示了如何创建和启动进程,以及进程间的通信方式,如队列等。此外,还提到了更高级的功能,例如进程池管理和同步原语等。通过这些实例,读者能更好地理解如何在实际项目中利用多核处理器的优势,同时注意进程间通信和同步等问题,确保程序稳定高效运行。
42 0
|
4月前
|
Python
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
在Python中,`multiprocessing`模块提供了一种在多个进程之间共享数据和同步的机制。
|
4月前
|
Java 调度 Windows
Java面试之程序、进程、线程、管程和并发、并行的概念
Java面试之程序、进程、线程、管程和并发、并行的概念
29 0
进程管理,每一个程序运行,都会有一个独有的ID,进程号
进程管理,每一个程序运行,都会有一个独有的ID,进程号