Filesystem, Data Structures, and System Calls
Filesystem Data Structures
- Process Management: linux maintains a data structure for each active process. process control blocks, stored in the process table
- Descriptor Table: process control blocks store many things, CPU state, contain the descriptor table. Use read, write, close to interact with descriptors.
- Open File Table: An open file table entry maintains information about an active session with a file (or something that behaves like a file, like a terminal or network connection). It keeps track of mode, refcount, vnode, etc.
vnode
- Static Information: The
vnodecontains static information about a file or file-like resource. - Details Stored: It stores file type (e.g., regular file, directory, symlink, terminal), a refcount, and the collection of function pointers used to read and write. The
vnodeacts as aninodecache for quicker access.
System Calls
- Memory Perception: Each process operates as if it owns all of main memory, but no process actually uses all 2^64 bytes of its address space.
- Memory Segments: Segments include user stack, heap, data, code, bss, and shared library.
- Parameter Passing: The first six parameters are passed through: %rdi, %rsi, %rdx, %rcx, %r8, %r9.
- System Call Execution: Executing syscall prompts an interrupt handler to execute in superuser mode. The return value is in %rax, and then iretq is executed.
Introduction to Multiprocessing
-
Process Definition: A process is an instance of a program's execution with a unique ID.
-
fork System Call: To launch a second process, the
forksystem call is used. It creates a new process that starts after the original, parent, process. Both processes continue execution after theforkcall. -
Return Values:
forkreturns a pid_t (an integer) to both processes. The parent process gets the PID of the child process, while the child process gets a return value of 0. -
Memory Replication: All memory is identical between the parent and child, though it is not shared (it is copied).
-
Debugging Multiple Processes: gdb has built-in support for debugging multiple processes:
set detach-on-fork off: Tells gdb to capture any fork'd processes, though it pauses them upon the fork.info inferiors: Lists the processes that gdb has captured.inferiors X: Switches to a different process to debug it.detach inferiors X: Tells gdb to stop watching the process and continue it.
-
Differences Between Parent and Child: Each process has a unique process ID. The return value of fork differs in the two processes and can be used to dispatch them in different directions.
文件系统、数据结构与系统调用
文件系统数据结构
- 进程管理 :linux 为每个活动进程维护一个数据结构,即 process control blocks,存储在 process table 中。
- 描述符表 :进程控制块存储了许多内容,包括 CPU 状态和 descriptor table。使用 read、write、close 与描述符交互。
- 打开文件表 :open file table entry 用于维护与文件(或类似文件的对象,如终端或网络连接)活动会话的信息。它跟踪 mode、refcount、vnode 等内容。
vnode
- 静态信息 :
vnode包含关于文件或类似文件资源的静态信息。 - 存储细节 :它存储 文件类型(例如普通文件、目录、符号链接、终端等)、refcount 以及用于读取和写入的 function pointers 集合。
vnode作为inode缓存,以便更快地访问。
系统调用
- 内存感知 :每个进程都像拥有全部主内存一样运行,但实际上没有进程使用其地址空间的全部 2^64 字节。
- 内存段 :包括 user stack、heap、data、code、bss 和 shared library 段。
- 参数传递 :前六个参数通过 %rdi、%rsi、%rdx、%rcx、%r8、%r9 传递。
- 系统调用执行 :执行 syscall 会触发超级用户模式下的中断 handler。返回值在 %rax 中,然后执行 iretq。
多进程介绍
-
进程定义 :进程是程序执行的一个实例,具有唯一的 ID。
-
fork 系统调用 :要启动第二个进程,使用
fork系统调用。它创建一个新进程,在原始父进程之后开始。两个进程都在fork调用后继续执行。 -
返回值 :
fork向两个进程返回一个 pid_t(整数)。父进程得到子进程的 PID,而子进程得到 0 的返回值。 -
内存复制 :父进程和子进程之间的所有内存都是相同的,但它们并未共享(而是被复制)。
-
调试多个进程 :gdb 内置支持调试多个进程:
set detach-on-fork off:告诉 gdb 捕获任何 fork'd 进程,但在 fork 时会暂停它们。info inferiors:列出 gdb 捕获的进程。inferiors X:切换到不同的进程进行调试。detach inferiors X:告诉 gdb 停止监视该进程并继续其运行。
-
父进程与子进程的区别 :每个进程都有唯一的进程 ID。fork 在两个进程中的返回值不同,可用于将它们派往不同方向。
费曼学习
Why: 与我何干?
了解文件系统数据结构、系统调用和多进程的知识,可以帮助你更好地理解计算机操作系统是如何工作的。比如,当你在电脑上运行程序、保存文件或者打开多个应用程序时,这些知识能让你明白背后发生了什么,还能帮助你更高效地编写和调试程序。
What: 定义、概念解释,可以做什么
- 文件系统数据结构:就像一个精心设计的图书馆系统,帮助计算机管理文件和目录。操作系统用它来记录文件的位置、大小、类型等信息,方便快速找到和操作文件。
- 系统调用:可以看作是用户程序和操作系统之间的“桥梁”。程序通过系统调用请求操作系统的服务,比如读写文件、创建进程等。
- 多进程:想象一下你同时在电脑上听音乐、写文档和浏览网页,这就是多进程。操作系统能让多个程序同时运行,每个程序就像一个独立的小助手,做自己的事情,互不干扰。
How: 步骤流程方法,以及解释所需的任何主题内容
- 文件系统数据结构:
- 进程控制块(Process Control Block, PCB):每个活跃的进程都有一个对应的PCB,它存储在进程表中。PCB就像一个“身份证”,记录了进程的各种信息,比如CPU状态、文件描述符表等。文件描述符表是用来管理文件描述符的,文件描述符就像是文件的“门牌号”,通过它可以用
read、write、close等操作来和文件交互。 - 打开文件表项(Open File Table Entry):用来维护一个文件(或者类似文件的东西,比如终端、网络连接)的活动会话信息。它会记录文件的模式(比如是只读还是可读写)、引用计数(有多少个进程打开了这个文件)等信息。
- vnode:存储了关于文件或类似文件资源的静态信息。它就像一个“信息卡片”,记录了文件类型(普通文件、目录、符号链接、终端等)、引用计数,还有一组用于读写等操作的函数指针。vnode可以看作是inode的缓存,访问速度更快。
- 进程控制块(Process Control Block, PCB):每个活跃的进程都有一个对应的PCB,它存储在进程表中。PCB就像一个“身份证”,记录了进程的各种信息,比如CPU状态、文件描述符表等。文件描述符表是用来管理文件描述符的,文件描述符就像是文件的“门牌号”,通过它可以用
- 系统调用:
- 每个进程都像是在一个虚拟的“房间”里,觉得自己拥有所有的内存空间,但实际上并没有真正使用所有的内存空间。内存空间被分成了不同的“区域”,比如用户栈、堆、数据、代码等,还有bss段和共享库。
- 当执行系统调用时,会触发一个中断,操作系统会切换到超级用户模式来处理这个请求。系统调用的前六个参数通过寄存器
%rdi、%rsi、%rdx、%rcx、%r8、%r9传递给操作系统。处理完后,返回值会放在%rax寄存器中,然后执行iretq指令返回到用户程序。
- 多进程:
- 进程的定义:进程是一个正在运行的程序的实例。可以通过
getpid系统调用来获取当前进程的进程ID。 - fork系统调用:用来创建一个新的进程,也就是子进程。子进程从父进程的下一条指令开始执行,父进程也会继续执行下一条指令。
fork在父进程和子进程中都会返回一个值,父进程得到子进程的进程ID,子进程得到返回值0,表示自己是子进程。父进程和子进程的所有内存内容都是一样的,但并不是共享的,而是被复制了一份。 - 调试多进程:如果想同时调试父进程和子进程,可以使用
gdb调试器。设置set detach-on-fork off让gdb捕获所有fork产生的进程,虽然会暂停它们;用info inferiors查看gdb捕获的所有进程;用inferiors X切换到不同的进程进行调试;用detach inferiors X让gdb停止监视某个进程,让它继续运行。 - 父进程和子进程的区别:它们都有唯一的进程ID。
fork的返回值在两个进程中不一样,父进程得到子进程的ID,子进程得到0,可以根据这个返回值让父进程和子进程做不同的事情。
- 进程的定义:进程是一个正在运行的程序的实例。可以通过
How Good: 可以给听众带来什么好处,什么改变
- 文件系统数据结构:能让你更好地理解文件是如何被管理的,有助于你高效地组织和操作文件,比如在编写文件操作相关的程序时,能更清楚地知道如何与操作系统交互。
- 系统调用:让你明白程序是如何请求操作系统服务的,有助于你编写更稳定、高效的程序,还能帮助你理解程序在运行过程中和操作系统之间的交互过程。
- 多进程:让你了解操作系统是如何同时处理多个任务的,能帮助你更好地设计和调试多进程程序,提高程序的并发性能,让你的程序能更高效地利用计算机资源。