# Week <3> — Team <27> **Members:** @111006239, @112062124, @111000116 (student IDs) :::info You can write in Chinese. ::: ## Lecture & Reading Notes - **fork()** : The fork system call creates a new process by duplicating the calling process. **Note / 備註** : Some states are copied (e.g., Program Counter, Stack, Open File Descriptors), while some are different (e.g., PID, Parent PID, Pending Signals). - **exec()** : The exec system call replaces the current process image with a new program. **Note / 備註** : It does not create a new process; instead, it overwrites the current one’s code, data, stack, and heap with the new program, but keeps the same PID and open file descriptors. - **waitpid()** : The waitpid system call makes a parent process wait for a specific child process to finish. **Note / 備註**: It suspends the parent until the child exits, then returns the child’s PID and exit status; this prevents zombie processes by releasing the child’s resources. - **Zombie process** : A zombie process is a child process that has finished execution but still has an entry in the process table because the parent has not yet collected its exit status. **Note / 備註**: <span style="background-color:#add8e6; font-family:Courier New; font-size:16px; font-weight:bold; color:#000080"> It does not execute any code or occupy CPU/memory</span>, but only consumes a process table entry; once the parent calls wait/waitpid, it will be cleared. Or else, if the parant terminates, 'init' will automatically reap the zombie process. - **Orphan process**: An orphan process is a child process whose ==parent has terminated while the child is still running==. The orphan is then adopted by <span style="background-color:#add8e6; font-family:Courier New; font-size:16px; font-weight:bold; color:#000080">the `init` process (PID 1)</span>, which takes responsibility for reaping it. **Note / 備註** : It continues execution normally, but once it finishes, `init` will collect its exit status to prevent it from becoming a zombie. - **Double fork**: The double fork technique is a common method to create a daemon process. The first child process immediately forks a second child and then exits, while the grandchild is adopted by `init` (PID 1). This ensures that the grandchild will not become a zombie. **Note / 備註** : By performing two forks, the intermediate child terminates quickly, and the grandchild is re-parented to `init`, which will properly reap it when it finishes. ### Shio (Explorations & Discoveries) - Genuine questions that arose from the videos/reading (e.g., “Why does X hold under Y?”, “Does this assumption break on Z?”). - Show how you sought answers: website, short experiments, citations, logs, or your own reasoning. - <span style="background-color:#add8e6; font-family:Courier New; font-size:16px; font-weight:bold; color:#000080">Will the zombie process be handled in the same way as the Linux host when run on a Docker container </span>? **Answer**: No, as the program we run in Docker container will be PID = 1 by default. Since it doesn't reap the child properly, the zombie process will occur. To solve this, we can use 'tini' which act as an init process, and will properly reap the zombie process by specifying this agrument 'docker run --init'. **Source**: Stack Overflow - Docker - init, zombies - why does it matter? [StackOverflow](https://stackoverflow.com/questions/49162358/docker-init-zombies-why-does-it-matter) - 為什麼 <span style="background-color:#add8e6; font-family:Courier New; font-size:16px; font-weight:bold; color:#000080">Zombie process does not execute any code or occupy CPU/memory </span>? **Answer**: Because the process has already terminated — its code, data, stack, and heap have been released. What remains is only a small entry in the process table (with PID, exit status, etc.), waiting for the parent process to collect it using `wait` or `waitpid`. 備註:所以會占用,但非常少。 **Source**: Wikipedia — Zombie process: *“It is not an active process; it is a process that has completed execution and has no memory allocated to it.”* [wiki](https://en.wikipedia.org/wiki/Zombie_process) - 為什麼 <span style="background-color:#add8e6; font-family:Courier New; font-size:16px; font-weight:bold; color:#000080">the `init` process (PID 1) adopt the orphan not the kernel (PID 0)</span> ? **Answer**: Because in Unix-like systems, all user processes are part of a parent-child hierarchy in **user space**. When a parent terminates, the kernel automatically reassigns the orphan to a designated user-space process (`init`, PID 1). `init` is chosen because: 1. It is the **first user process** started by the kernel during boot, and it never terminates. 2. It runs in **user space**, so it can safely call `wait()`/`waitpid()` to collect exit statuses. 3. The kernel itself (PID 0) is not a normal process — it is the scheduler/idle task, not capable of performing `wait()` on user processes. **Source**: - Wikipedia — Orphan process: *“In Unix-like operating systems, orphaned processes are immediately adopted by init (process ID 1), which becomes their new parent process.”* [wiki](https://en.wikipedia.org/wiki/Orphan_process) --- ## Hand-on Lab ### Answers to Reflection Questions **Q1. How is it possible to run so many “virtual CPUs” on a machine with only 2 physical CPU cores?** 實際上並沒有這麼多的真實 CPU,或者說,虛擬 CPU(vCPU)並沒有直接提升硬體速度。 它是一個名為 **hypervisor(虛擬機管理程式 / 虛擬化層)** 的系統所提供的「假想硬體」。 但這並不是沒有意義。 它讓使用者可以更方便地設定與操控「要分配多少 CPU 資源」給不同的虛擬機或容器。 至於要怎麼把這些虛擬 CPU 的工作實際分配到有限的物理核心,就要交給 **operating system scheduler(作業系統排程器)** 來處理。 具體來說,**hypervisor 與作業系統排程器**會根據一些規則(例如時間片 *time-slicing*、優先權 *priority*、多工需求 *multi-tasking needs*),將這些 vCPU 的工作在不同時間點分派到真實的 CPU 執行緒(threads)上。 因此,雖然只有 2 個物理核心,使用者卻「看起來」好像擁有更多的 CPU 可以運算。 參考 : https://serverfault.com/questions/1135918/how-do-physical-multi-core-cpus-relate-to-vcpus?utm_source=chatgpt.com **Q2. What do you think would happen to the performance of all the VMs if one of them started running a very CPU-intensive application (like a game)?** If one VM starts a CPU-intensive task, it will hog up all the CPU time. This will result in the rest of the VMs getting less CPU time, which will run slower; they will feel laggy, response time will increase, and CPU-related tasks will be done more slowly. ### Shio (Explorations & Discoveries) - Extra question(s) we asked: - Q: <...> A: <what we found / how we tested> - Our Discovery(ies): ### What I learned (each member writes 2–4 sentences, in their own words) ### @111000116 virtual machine會透過hyperviser模擬一套虛擬硬體,docker則是透過docker engine直接運作。 ### @112062124 1. 我學到一些簡單的 commands 背後的運作原理,雖然不知道也可以使用,但知道後可以避免一些難以判斷原因的 bug。 2. 在其他課程中也有使用到虛擬機,但並沒有提到為什麼不用 container。現在我了解了,雖然 container 很方便,但它實際上是共享同一個作業系統的 kernel,在環境隔離上仍可能不如虛擬機理想。 3. 有時候虛擬化並不是要讓使用者誤解他們電腦的能力,而是為了讓使用者即使不完全理解底層硬體配置,也能合理並有效地使用資源。 ### @111006239 - I understand how basic things we use in every day life work. For example, typing a cmd on a terminal, making a SSH connection, are all involved in fork(), exec(), and daemon process. - VM will run on a hypervisor, and it's isolated from the host's kernel, while Docker containers runs on Docker Engine and share the host's kernel. - The reason why running programs in linux most of the time doesn't require you to search the commands is because the "Everything is a File" philosophy. It makes everything much easier. - I now understand how PATH variables work, eventhough we're using them all the time without noticing it and understand how it works. ## Content Sharing Agreement **Please uncheck if you disagree!** - [X] We agree that excerpts of this note may be shared by TA to Discord if our team's note is selected as *shio* highlight. - [X] We agree that our team ID may be shown on Discord if our team's note is selected as *shio* highlight. - [X] We agree that the instructore can show excerpts of this note if our team's note is selected as *shio* highlight. :::warning * Please don't share this HackMD note directly with non-teammate. But you are encouraged to help others (including non-teammate) on Discord. [Follow our collaboration policy](https://sys-nthu.github.io/os25-fall/admin/policies.html#collaboration-citation) * Please don't peek at or copy another team's HackMD, or using LLM to generate your reflection. :::