05 · Operating Systems
05 · ระบบปฏิบัติการ
This chapter is the floor directly above the machine — where one processor is made to behave like a room full of them, and where the machine stops being something a program owns.
บทนี้คือชั้นที่วางอยู่เหนือตัวเครื่องขึ้นมาโดยตรง — ที่ซึ่งโปรเซสเซอร์ตัวเดียวถูกทำให้ทำตัวเหมือนมีอยู่เต็มห้อง และที่ซึ่งเครื่องเลิกเป็นสมบัติของโปรแกรมใดโปรแกรมหนึ่ง
How does one machine pretend to be many, safely?
เครื่องเดียวแสร้งทำเป็นหลายเครื่องอย่างปลอดภัยได้อย่างไร
Between June 1985 and January 1987, six patients treated with a radiation machine called the Therac-25 received massive overdoses; at least three died. The machine was not broken in any way an engineer could see. Its predecessor had carried hardware interlocks — physical devices that made the dangerous configuration impossible — and on the Therac-25 they had been removed, because software would check instead. Nancy Leveson and Clark Turner found that the software checked, but that two of its concurrent tasks shared variables with no synchronization, so an operator typing quickly could change the treatment mode after the check had read it and before the hardware had finished moving (Leveson & Turner, IEEE Computer, July 1993). They also record what the machine was running on: "The system is not built using a standard operating system or executive. Rather, the real-time executive was written especially for the Therac-25" — by a single programmer, in assembly language, over several years.
ระหว่างเดือนมิถุนายน 1985 ถึงมกราคม 1987 ผู้ป่วยหกคนที่รักษาด้วยเครื่องฉายรังสีชื่อ Therac-25 ได้รับรังสีเกินขนาดอย่างรุนแรง อย่างน้อยสามคนเสียชีวิต ตัวเครื่องไม่ได้เสียในแบบที่วิศวกรมองเห็นได้ เครื่องรุ่นก่อนหน้ามีกลไกล็อกฮาร์ดแวร์ (hardware interlock) — อุปกรณ์ทางกายภาพที่ทำให้การตั้งค่าอันตรายเกิดขึ้นไม่ได้ — และใน Therac-25 อุปกรณ์เหล่านั้นถูกถอดออก เพราะจะให้ซอฟต์แวร์ตรวจสอบแทน Nancy Leveson และ Clark Turner พบว่าซอฟต์แวร์ตรวจสอบจริง แต่งาน (task) ที่ทำงานพร้อมกันสองงานใช้ตัวแปรร่วมกันโดยไม่มีการซิงโครไนซ์ ผู้ปฏิบัติงานที่พิมพ์เร็วจึงเปลี่ยนโหมดการรักษาได้ หลังการตรวจสอบอ่านค่าไปแล้ว แต่ก่อนฮาร์ดแวร์เคลื่อนที่เสร็จ (Leveson & Turner, IEEE Computer, July 1993) ทั้งสองยังบันทึกไว้ด้วยว่าเครื่องรันอยู่บนอะไร — "ระบบนี้ไม่ได้สร้างขึ้นด้วยระบบปฏิบัติการหรือ executive มาตรฐาน แต่ real-time executive ถูกเขียนขึ้นมาเฉพาะสำหรับ Therac-25" — โดยโปรแกรมเมอร์คนเดียว เขียนด้วยภาษาแอสเซมบลี ตลอดเวลาหลายปี
That last sentence is the reason this chapter exists. An operating system is not a convenience layer. It is the accumulated answer to three problems lethal to solve again from scratch: how one machine is shared, how concurrent things stay coherent, and how anything survives being switched off. Remzi and Andrea Arpaci-Dusseau call them virtualization, concurrency, and persistence (Operating Systems: Three Easy Pieces). The unifying idea is that an operating system is a machine that lies, carefully: every service it offers is a falsehood about the floor below, maintained well enough to be relied on.
ประโยคสุดท้ายนั้นคือเหตุผลที่บทนี้มีอยู่ ระบบปฏิบัติการ (operating system) ไม่ใช่ชั้นอำนวยความสะดวก มันคือคำตอบสะสมของปัญหาสามข้อที่อันตรายถึงตายหากต้องแก้ใหม่จากศูนย์ — เครื่องเดียวถูกแบ่งกันใช้อย่างไร สิ่งที่ทำงานพร้อมกันคงความสอดคล้องไว้อย่างไร และอะไรรอดจากการถูกปิดเครื่อง Remzi และ Andrea Arpaci-Dusseau เรียกสามข้อนี้ว่า การทำเสมือน (virtualization) การทำงานพร้อมกัน (concurrency) และความคงอยู่ของข้อมูล (persistence) (Operating Systems: Three Easy Pieces) ไอเดียที่ร้อยทั้งหมดเข้าด้วยกันคือ ระบบปฏิบัติการเป็นเครื่องที่โกหกอย่างระมัดระวัง บริการทุกอย่างที่มันเสนอคือความเท็จเกี่ยวกับชั้นข้างล่าง รักษาไว้ดีพอจะพึ่งพาได้
The first lie is arithmetic. Your laptop has a handful of processors and is running hundreds of programs, each written as though it had a machine to itself. The operating system multiplexes: it runs one program for a few milliseconds, saves every register, loads another's, and lets a hardware timer interrupt it so that no program can decline to give the machine back. The larger lie is about memory. The Atlas machine at Manchester, running in 1962, introduced a "one-level storage system": programs addressed a store far larger than physical memory, and hardware quietly moved pages between core and drum (Kilburn, Edwards, Lanigan & Sumner, 1962). Every process since has been handed the same fiction — virtual memory, as every descendant calls it: a private address space, starting at zero, that appears to be all its own. Two programs can both hold "address 4096" and never meet.
คำโกหกแรกคือเรื่องเลขคณิต แล็ปท็อปของคุณมีโปรเซสเซอร์ไม่กี่ตัว แต่รันโปรแกรมอยู่นับร้อย แต่ละตัวเขียนขึ้นราวกับมีเครื่องทั้งเครื่องเป็นของตัวเอง ระบบปฏิบัติการทำ multiplex — รันโปรแกรมหนึ่งไปสองสามมิลลิวินาที บันทึกค่าในทุกรีจิสเตอร์ โหลดค่าของอีกโปรแกรมเข้ามา และปล่อยให้ตัวจับเวลาฮาร์ดแวร์ขัดจังหวะมัน เพื่อไม่ให้โปรแกรมไหนปฏิเสธที่จะคืนเครื่องได้ คำโกหกที่ใหญ่กว่าคือเรื่องหน่วยความจำ เครื่อง Atlas ที่ Manchester ซึ่งรันในปี 1962 เปิดตัว "ระบบเก็บข้อมูลชั้นเดียว" (one-level storage system) — โปรแกรมอ้างที่อยู่ในพื้นที่เก็บข้อมูลที่ใหญ่กว่าหน่วยความจำจริงมาก และฮาร์ดแวร์ย้าย page ระหว่าง core กับ drum อย่างเงียบๆ (Kilburn, Edwards, Lanigan & Sumner, 1962) ทุกโพรเซส (process) นับแต่นั้นได้รับเรื่องแต่งเดียวกัน — หน่วยความจำเสมือน (virtual memory) อย่างที่ลูกหลานทุกตัวเรียกกัน คือพื้นที่ที่อยู่ส่วนตัว เริ่มจากศูนย์ ดูเหมือนเป็นของมันเองทั้งหมด โปรแกรมสองตัวถือ "address 4096" เดียวกันได้โดยไม่มีวันเจอกัน
A lie is only safe if it cannot be inspected from inside; here the operating system depends on the floor below. The kernel is not privileged because it is cleverer than your program; it is privileged because the processor refuses certain instructions unless a mode bit is set. Multics defined eight such rings of protection; x86 inherited the idea with four, of which mainstream systems use two — kernel and user (Multics protection). Chapter 04's instruction set does not know what a process is; it knows only that some instructions are forbidden in the outer mode, and that attempting one traps. Everything about isolation, security, and multi-tenancy is built from that single hardware gesture.
คำโกหกปลอดภัยก็ต่อเมื่อมันถูกตรวจสอบจากข้างในไม่ได้ ตรงนี้เองระบบปฏิบัติการต้องพึ่งชั้นข้างล่าง เคอร์เนล (kernel) ไม่ได้มีสิทธิพิเศษเพราะฉลาดกว่าโปรแกรมของคุณ มันมีสิทธิพิเศษเพราะโปรเซสเซอร์ปฏิเสธคำสั่งเครื่องบางตัว เว้นแต่มีการตั้ง mode bit ไว้ Multics นิยามวงแหวนการป้องกัน (ring) แบบนี้ไว้แปดชั้น x86 รับไอเดียนี้มาด้วยสี่ชั้น และระบบกระแสหลักใช้จริงสองชั้น — เคอร์เนลกับผู้ใช้ (Multics protection) instruction set ของบทที่ 04 ไม่รู้ว่าโพรเซส (process) คืออะไร มันรู้แค่ว่าคำสั่งเครื่องบางตัวถูกห้ามในโหมดนอก และการพยายามรันมันทำให้เกิด trap ทุกเรื่องเกี่ยวกับ isolation ความปลอดภัย และ multi-tenancy สร้างขึ้นจากท่าทีเดียวของฮาร์ดแวร์ท่านี้
The second problem, concurrency, is the one that killed the Therac patients. Once two things run at once and touch the same data, correctness stops being a property of either one alone. Edsger Dijkstra gave the field its basic tool in 1965, the semaphore, in notes titled "Cooperating Sequential Processes", and used it to build the layered THE system (CACM, May 1968). But mutual exclusion trades one failure for another: a process holding one lock while waiting for a second can wait forever. Coffman, Elphick and Shoshani named the four conditions that must all hold for deadlock — mutual exclusion, hold-and-wait, no preemption, and circular wait — in ACM Computing Surveys in 1971 (System Deadlocks). Break any one and deadlock is impossible; that is still how it is handled. Notice what the operating system offers: not a removal of the difficulty but primitives correct enough to build on. The honest reading of the Therac-25 is that an engineer who declines them is re-deriving 1965 alone, under deadline.
ปัญหาที่สอง การทำงานพร้อมกัน (concurrency) คือสิ่งที่ฆ่าผู้ป่วย Therac พอสองสิ่งทำงานพร้อมกันและแตะข้อมูลก้อนเดียวกัน ความถูกต้องเลิกเป็นคุณสมบัติของฝ่ายใดฝ่ายหนึ่งลำพัง Edsger Dijkstra มอบเครื่องมือพื้นฐานให้วงการนี้ในปี 1965 คือ semaphore ในบันทึกชื่อ "Cooperating Sequential Processes" และใช้มันสร้างระบบ THE ที่แบ่งเป็นชั้น (CACM, May 1968) แต่ mutual exclusion แลกความล้มเหลวแบบหนึ่งไปกับอีกแบบหนึ่ง โพรเซสที่ถือล็อก (lock) ตัวหนึ่งไว้ระหว่างรอล็อกตัวที่สอง อาจรอไปตลอดกาล Coffman, Elphick และ Shoshani ตั้งชื่อเงื่อนไขสี่ข้อที่ต้องเป็นจริงพร้อมกันทั้งหมดจึงจะเกิด deadlock — mutual exclusion, hold-and-wait, no preemption และ circular wait — ใน ACM Computing Surveys ปี 1971 (System Deadlocks) ตัดข้อใดข้อหนึ่งออก deadlock ก็เป็นไปไม่ได้ นั่นยังคือวิธีจัดการกับมันจนถึงทุกวันนี้ สังเกตว่าระบบปฏิบัติการเสนออะไรให้ ไม่ใช่การกำจัดความยาก แต่เป็น primitive ที่ถูกต้องพอจะต่อยอดได้ การอ่าน Therac-25 อย่างตรงไปตรงมาคือ วิศวกรที่ปฏิเสธเครื่องมือเหล่านี้ กำลังนั่งคิดค้นปี 1965 ขึ้นมาใหม่คนเดียว ภายใต้ deadline
The third lie is that storage remembers. It does — but power can be cut between any two instructions, including the two that would have left the disk in a sensible state. The operating system's answer is fsync, which returns only when data has reached the device, and file systems that journal their intentions, so a half-finished operation can be replayed or undone. The abstraction leaks badly: fsync on a new file does not make the file's directory entry durable — you must sync the parent directory too. When Pillai and colleagues checked how eleven widely used applications behaved across crashes, they found sixty distinct crash vulnerabilities (All File Systems Are Not Created Equal, OSDI 2014). These were not amateur programs. The surface says "saved," and only the floor below knows whether that is true.
คำโกหกที่สามคือ ที่เก็บข้อมูลจดจำได้ มันจำได้จริง — แต่ไฟถูกตัดได้ระหว่างคำสั่งเครื่องสองตัวใดๆ รวมถึงสองตัวที่จะทิ้งดิสก์ไว้ในสถานะ (state) ที่สมเหตุสมผล คำตอบของระบบปฏิบัติการคือ fsync ซึ่งจะ return ก็ต่อเมื่อข้อมูลไปถึงอุปกรณ์แล้ว และระบบไฟล์ (file system) ที่จด journal ความตั้งใจของตัวเองไว้ เพื่อให้ operation ที่ค้างอยู่ครึ่งเดียวถูกเล่นซ้ำหรือย้อนกลับได้ นามธรรม (abstraction) ตัวนี้รั่วอย่างหนัก — fsync บนไฟล์ใหม่ไม่ได้ทำให้ directory entry ของไฟล์นั้นคงทนถาวรไปด้วย คุณต้อง sync ไดเรกทอรีแม่ด้วย เมื่อ Pillai และเพื่อนร่วมงานตรวจสอบว่าแอปพลิเคชันที่ใช้กันแพร่หลาย 11 ตัวมีพฤติกรรมอย่างไรเมื่อเครื่อง crash พวกเขาพบช่องโหว่ตอน crash ที่ต่างกัน 60 จุด (All File Systems Are Not Created Equal, OSDI 2014) โปรแกรมพวกนี้ไม่ใช่ของมือสมัครเล่น ผิว (surface) บอกว่า "บันทึกแล้ว" มีแต่ชั้นข้างล่างเท่านั้นที่รู้ว่าจริงหรือเปล่า
One design rule holds the whole thing together: separate mechanism from policy. The kernel supplies the machinery to do a thing and leaves the decision of what to do to whoever is above it. Hydra stated it as a design principle in 1974 (Wulf et al., CACM 17, no. 6), and Butler Lampson's "Hints for Computer System Design" made it common sense by 1983. The reason is simple: policy changes far faster than mechanism, and a kernel that bakes in a scheduling preference or a security model must be rewritten when opinion moves. The interface that results is astonishingly narrow for what it carries: the x86-64 system call table in the current Linux source lists 385 entries (kernel source, checked 1 August 2026). Everything you have ever run passed through that door.
กฎการออกแบบข้อเดียวยึดทุกอย่างไว้ด้วยกัน คือแยก กลไก (mechanism) ออกจาก นโยบาย (policy) เคอร์เนลจัดหากลไกให้ทำสิ่งหนึ่ง และปล่อยการตัดสินใจว่าจะทำอะไรให้เป็นเรื่องของสิ่งที่อยู่เหนือมันขึ้นไป Hydra ระบุเรื่องนี้เป็นหลักการออกแบบตั้งแต่ปี 1974 (Wulf et al., CACM 17, no. 6) และ "Hints for Computer System Design" ของ Butler Lampson ทำให้มันเป็นสามัญสำนึกภายในปี 1983 เหตุผลนั้นง่าย — นโยบายเปลี่ยนเร็วกว่ากลไกมาก และเคอร์เนลที่ฝังความชอบเรื่อง scheduling หรือแบบจำลองความปลอดภัยไว้ตายตัว ต้องถูกเขียนใหม่ทุกครั้งที่ความเห็นขยับ อินเทอร์เฟซที่ได้ออกมาแคบเมื่อเทียบกับสิ่งที่มันแบกไว้ — ตาราง system call ของ x86-64 ใน Linux source ปัจจุบันมี 385 รายการ (kernel source, checked 1 August 2026) ทุกอย่างที่คุณเคยรันผ่านประตูบานนั้นมาแล้ว
The people here inherited each other directly. Fernando Corbató demonstrated the Compatible Time-Sharing System at MIT in 1961 and then led Multics, whose ambition was computing sold like electricity — a utility, always on, shared by strangers. Bell Labs pulled out in 1969, and Dennis Ritchie's account of what followed is unglamorous: the Labs refused to buy a replacement machine, so "it did not take long, therefore, for Thompson to find a little-used PDP-7" (Ritchie, The Evolution of the Unix Time-sharing System). Ken Thompson wrote the first Unix on it in about a month, in the summer of 1969, while his wife was away — "essentially one person for a month, it was just myself," he said later (oral history, 1989). Multics tried to specify everything; Unix was small because it had no budget to be large, and the small one spread. Thompson and Ritchie received the Turing Award in 1983, Corbató in 1990.
คนในเรื่องนี้สืบทอดกันมาโดยตรง Fernando Corbató สาธิต Compatible Time-Sharing System ที่ MIT ในปี 1961 และนำทีม Multics ต่อ ความทะเยอทะยานของมันคือขายการคำนวณอย่างที่ขายไฟฟ้า — สาธารณูปโภคที่เปิดตลอดเวลา แบ่งกันใช้ระหว่างคนแปลกหน้า Bell Labs ถอนตัวในปี 1969 และเรื่องเล่าของ Dennis Ritchie ว่าอะไรเกิดขึ้นต่อมานั้นไม่หรูหรา ทาง Labs ปฏิเสธจะซื้อเครื่องทดแทน ดังนั้น "จึงไม่ต้องใช้เวลานานนักที่ Thompson จะหา PDP-7 เครื่องหนึ่งที่แทบไม่มีใครใช้เจอ" ("it did not take long, therefore, for Thompson to find a little-used PDP-7") (Ritchie, The Evolution of the Unix Time-sharing System) Ken Thompson เขียน Unix ตัวแรกลงเครื่องนั้นในเวลาประมาณหนึ่งเดือน ในฤดูร้อนปี 1969 ขณะภรรยาไม่อยู่บ้าน — "โดยพื้นฐานแล้วคือคนคนเดียวทำเป็นเวลาหนึ่งเดือน มีแค่ผมคนเดียวเท่านั้น" ("essentially one person for a month, it was just myself") เขาเล่าไว้ในภายหลัง (oral history, 1989) Multics พยายามระบุทุกอย่างไว้ล่วงหน้า ส่วน Unix เล็กเพราะไม่มีงบให้ใหญ่ และตัวที่เล็กกว่านั่นเองที่แพร่ออกไป Thompson กับ Ritchie ได้รับรางวัล Turing Award ในปี 1983 ส่วน Corbató ได้รับในปี 1990
Connections
เชื่อมโยง
Below is 04, which supplies everything that makes the illusion enforceable: privileged mode, the timer interrupt, and address-translation hardware. Above it, 06 compiles programs against the process abstraction described here. Chapter 07 carries the same instinct upward — hide the decision that will change, publish only the interface — and chapter 08 is largely the story of one application refusing to trust this floor's persistence guarantees and rebuilding them itself. Chapter 10 asks what happens to all of this when the "one machine" is a thousand of them, and chapter 11 treats the kernel boundary as the line an attacker is trying to cross.
ชั้นล่างคือบทที่ 04 ซึ่งจัดหาทุกอย่างที่ทำให้ภาพลวงตานี้บังคับใช้ได้จริง — โหมดสิทธิพิเศษ การขัดจังหวะของตัวจับเวลา และฮาร์ดแวร์แปลที่อยู่ เหนือขึ้นไป บทที่ 06 คอมไพล์โปรแกรมโดยอิงกับ abstraction ของโพรเซสที่อธิบายไว้ในบทนี้ บทที่ 07 พาสัญชาตญาณเดียวกันขึ้นไปอีกชั้น — ซ่อนการตัดสินใจที่จะเปลี่ยนแปลง เผยแพร่แค่อินเทอร์เฟซ — และบทที่ 08 ส่วนใหญ่คือเรื่องของแอปพลิเคชันหนึ่งตัวที่ปฏิเสธจะเชื่อการรับประกันความคงอยู่ของข้อมูล (persistence) ของชั้นนี้ และสร้างมันขึ้นมาใหม่เอง บทที่ 10 ถามว่าจะเกิดอะไรขึ้นกับทั้งหมดนี้ เมื่อ "เครื่องเดียว" กลายเป็นเครื่องนับพัน และบทที่ 11 มองพรมแดนของเคอร์เนลเป็นเส้นที่ผู้โจมตีพยายามข้าม
Open questions
คำถามที่ยังเปิดอยู่
Is the kernel still the right place for the boundary? Microkernels, unikernels, and in-kernel virtual machines each move the line, and none has settled the argument. The process abstraction was designed for a machine whose interesting hardware was the CPU; today much of the work happens on accelerators the kernel barely schedules. And why, after sixty years, is concurrency still where careful engineers are most likely to be wrong?
เคอร์เนลยังเป็นที่ที่ถูกต้องสำหรับวางพรมแดนนี้อยู่หรือไม่ microkernel, unikernel และ virtual machine ที่อยู่ในเคอร์เนล ต่างขยับเส้นนี้กันไปคนละทาง และยังไม่มีตัวไหนยุติข้อถกเถียงได้ abstraction ของโพรเซสถูกออกแบบมาสำหรับเครื่องที่ฮาร์ดแวร์สำคัญคือ CPU แต่ทุกวันนี้งานส่วนใหญ่เกิดขึ้นบนตัวเร่ง (accelerator) ที่เคอร์เนลแทบไม่ได้จัดคิวให้ และทำไมหลังผ่านมาหกสิบปี การทำงานพร้อมกัน (concurrency) ยังเป็นจุดที่วิศวกรที่รอบคอบมีโอกาสผิดพลาดมากที่สุด
Go deeper
อ่านต่อ
- Remzi H. Arpaci-Dusseau & Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces, version 1.10, 2023 — the clearest treatment of the three pieces, free online.
- Dennis M. Ritchie & Ken Thompson, "The UNIX Time-Sharing System," Communications of the ACM 17, no. 7 (July 1974): 365–375 — the design that most systems still imitate.
- Nancy G. Leveson & Clark S. Turner, "An Investigation of the Therac-25 Accidents," IEEE Computer 26, no. 7 (July 1993): 18–41 — the case every systems engineer should read once.
- Remzi H. Arpaci-Dusseau & Andrea C. Arpaci-Dusseau, Operating Systems: Three Easy Pieces, version 1.10, 2023 — บทความที่อธิบายสามชิ้นส่วนนี้ได้ชัดเจนที่สุด อ่านฟรีออนไลน์
- Dennis M. Ritchie & Ken Thompson, "The UNIX Time-Sharing System," Communications of the ACM 17, no. 7 (July 1974): 365–375 — การออกแบบที่ระบบส่วนใหญ่ยังเลียนแบบอยู่จนถึงทุกวันนี้
- Nancy G. Leveson & Clark S. Turner, "An Investigation of the Therac-25 Accidents," IEEE Computer 26, no. 7 (July 1993): 18–41 — เคสที่วิศวกรระบบทุกคนควรอ่านสักครั้ง