<?php
/**
 * ============================================================
 *  现代操作系统 · 第一章《操作系统概论》大白话 + 代码例子
 * ============================================================
 *  作用:49 个概念,每条 = 大白话 + 一段 PHP 代码示例。
 *  说明:硬件/历史类概念用 PHP 代码模拟其思想,
 *        系统调用类尽量用真实 PHP 函数演示。
 *  运行:php os_intro.php          全部
 *        php os_intro.php 37       看第 37 条
 *        php os_intro.php 内核     关键词搜索
 * ============================================================
 */

declare(strict_types=1);

final class Topic
{
    public function __construct(
        public readonly int $no,
        public readonly string $title,
        public readonly string $plain,
        public readonly string $code
    ) {}
}

final class OsIntroBook
{
    /** @var Topic[] */
    private array $topics = [];

    public function __construct()
    {
        $this->load();
    }

    private function load(): void
    {
        $data = [
            1 => ['什么是操作系统',
                '开机第一个跑、关机最后停的大管家,所有软件用硬件都得经它。',
                <<<'CODE'
// 程序不能直接碰硬件, 必须喊 OS 帮忙
$f = fopen('save.dat', 'r');   // 你喊一声, OS 去操作硬盘
fclose($f);
CODE],

            2 => ['操作系统作为扩展机器',
                '把复杂硬件操作包装成一句简单命令。',
                <<<'CODE'
$txt = file_get_contents('a.txt');  // 你只写一句
// 底层: open -> seek -> 读扇区 -> 缓冲 -> close 全被OS包好
CODE],

            3 => ['操作系统作为资源管理者',
                '决定 CPU、内存、硬盘谁先用、用多少。',
                <<<'CODE'
$mem = malloc_sim(1024);     // 向OS申请内存
use_memory($mem);
free_sim($mem);              // 还给OS, 再分给别人
CODE],

            4 => ['操作系统的历史',
                '从真空管到移动设备,一代代被硬件和需求逼着进化。',
                <<<'CODE'
$eras = ['1940真空管', '1960批处理', '1980个人机', '2010移动'];
foreach ($eras as $e) echo "$e -> ";
CODE],

            5 => ['第一代:真空管与穿孔卡片',
                '没有操作系统,程序打孔在纸卡上,亲自上机跑。',
                <<<'CODE'
// 穿孔卡片: 有孔=1, 无孔=0, 一行=一条指令
$card = [1, 0, 1, 1, 0, 0, 1];
$instruction = bindec(implode('', $card));
CODE],

            6 => ['第二代:晶体管与批处理系统',
                '把任务攒成一批,自动连续跑,省去人工换卡。',
                <<<'CODE'
$batch = ['job1', 'job2', 'job3'];   // 攒成一批
foreach ($batch as $job) {
    run($job);               // 自动一个接一个跑
}
CODE],

            7 => ['第三代:集成电路与多道程序设计',
                '一个程序等 I/O 时,CPU 切去跑另一个,不闲着。',
                <<<'CODE'
if ($A->waitingIO()) {
    switchTo($B);            // A等数据时, CPU去跑B
}
CODE],

            8 => ['第四代:个人计算机',
                '图形界面出现,鼠标点点就能用。',
                <<<'CODE'
// 事件驱动: 点击触发动作
on('click', fn() => openApp());
on('doubleclick', fn() => runProgram());
CODE],

            9 => ['第五代:移动计算机',
                '为触摸、省电、联网而设计。',
                <<<'CODE'
if ($battery < 20) {
    freezeBackgroundApps();  // 省电: 冻结后台App
}
CODE],

            10 => ['大型机操作系统',
                '海量并发事务,超级稳定,常年不关机。',
                <<<'CODE'
foreach ($millionsOfTransactions as $txn) {
    process($txn);           // 同时处理海量交易
}                            // 几十年不宕机
CODE],

            11 => ['服务器操作系统',
                '同时给很多用户提供网页、邮件等服务。',
                <<<'CODE'
$srv = stream_socket_server("tcp://0.0.0.0:80");
while ($client = stream_socket_accept($srv)) {
    handle($client);         // 服务大量用户
}
CODE],

            12 => ['多处理器操作系统',
                '把任务拆开分给多个 CPU 并行干。',
                <<<'CODE'
$cpus = 8;
$chunks = array_chunk($work, intdiv(count($work), $cpus));
foreach ($chunks as $i => $c) assignToCPU($i, $c);  // 分给8核
CODE],

            13 => ['个人计算机操作系统',
                '单用户多任务,伺候你一个人爽。',
                <<<'CODE'
$tasks = ['音乐', '文档', '下载'];
foreach ($tasks as $t) schedule($t);   // 同时跑, 伺候单用户
CODE],

            14 => ['掌上计算机操作系统',
                '内存极少,系统要精简省内存。',
                <<<'CODE'
if (memory_get_usage() > 4 * 1024 * 1024) {
    trimFeatures();          // 内存紧, 砍掉非核心功能
}
CODE],

            15 => ['嵌入式操作系统',
                '固定功能,死循环控制,绝对可靠。',
                <<<'CODE'
while (true) {               // 微波炉控制循环
    readKeypad();
    controlHeater();
}
CODE],

            16 => ['传感器节点操作系统',
                '电量算力极少,测完就睡省电。',
                <<<'CODE'
while (true) {
    $t = readTemp();
    send($t);
    sleep(3600);             // 测完睡一小时, 极省电
}
CODE],

            17 => ['实时操作系统',
                '必须在死线前响应,晚了出事。',
                <<<'CODE'
$deadline = 20;              // ms
if (elapsed() > $deadline) {
    panic("超时! 气囊未按时弹出");
}
CODE],

            18 => ['智能卡操作系统',
                '资源极小,只做身份验证与加密。',
                <<<'CODE'
// 银行卡/SIM卡芯片, 系统只有几KB
$ok = verifyPIN($input) && encrypt($data);
CODE],

            19 => ['处理器(CPU)',
                '取指—执行循环,一次只专心一小步。',
                <<<'CODE'
$pc = 0;
while (true) {
    $ins = fetch($pc);       // 取指令
    exec($ins);              // 执行
    $pc++;                   // 下一条
}
CODE],

            20 => ['多线程与多核芯片',
                '多核真并行;多线程让一个核空隙里再插活。',
                <<<'CODE'
$cores = 4; $threadsPerCore = 2;
echo $cores * $threadsPerCore;   // 看起来 8 个在跑
CODE],

            21 => ['存储器(总体)',
                '分层:越靠近 CPU 越快越贵越小。',
                <<<'CODE'
$hierarchy = ['寄存器', '缓存', '内存', '硬盘'];
// 速度: 快 -------------------> 慢
// 容量: 小 -------------------> 大
CODE],

            22 => ['高速缓存(Cache)',
                '把常用数据放手边,命中就直接拿。',
                <<<'CODE'
$cache = [];
function get($k) {
    global $cache, $mem;
    return $cache[$k] ?? ($cache[$k] = $mem[$k]);  // 命中直接返回
}
CODE],

            23 => ['内存(RAM)',
                '运行时的工作台,断电就清空。',
                <<<'CODE'
$ram = [];
$ram['doc'] = "未保存内容";
// 断电:
$ram = [];                   // 全没了!
CODE],

            24 => ['磁盘(硬盘)',
                '断电不丢的仓库,要用再搬进内存。',
                <<<'CODE'
file_put_contents('photo.jpg', $data);  // 写盘, 断电仍在
$data = file_get_contents('photo.jpg'); // 要用再读进内存
CODE],

            25 => ['非易失性存储器',
                '断电也不丢,如硬盘、U 盘、固态盘。',
                <<<'CODE'
file_put_contents('/usb/note.txt', '断电也在');
// 拔下U盘放一年, 插回:
echo file_get_contents('/usb/note.txt');  // 内容还在
CODE],

            26 => ['I/O 设备',
                '输入(键鼠)、输出(屏幕)、又读又写(硬盘网卡)。',
                <<<'CODE'
$in  = fopen('php://stdin', 'r');    // 输入
$out = fopen('php://stdout', 'w');   // 输出
fwrite($out, fgets($in));            // 进 -> 出
CODE],

            27 => ['设备控制器',
                'OS 不直接碰硬件,给控制器下命令。',
                <<<'CODE'
// OS 给硬盘控制器下命令, 不自己转盘片
$controller->command('READ', sector: 5);
CODE],

            28 => ['总线结构',
                '部件间传数据的公路,大家都挂在上面。',
                <<<'CODE'
$bus->transfer(from: 'CPU', to: 'RAM', data: $x);
$bus->transfer(from: 'RAM', to: 'GPU', data: $frame);
CODE],

            29 => ['系统启动过程',
                'BIOS 自检 → 找引导 → 加载内核 → 起桌面。',
                <<<'CODE'
$steps = ['BIOS自检', '找引导程序', '加载内核', '启动桌面'];
foreach ($steps as $s) echo "$s\n";
CODE],

            30 => ['进程的概念',
                '硬盘上的死代码跑起来、占了资源,就成活进程。',
                <<<'CODE'
$pid = pcntl_fork();         // 程序 -> 进程
if ($pid == 0) {
    echo "我是活进程\n";       // 占着内存和CPU
    exit;
}
CODE],

            31 => ['地址空间',
                '每个进程都以为独占内存,其实被映射隔离。',
                <<<'CODE'
$virtual  = 0x0000;          // 进程以为从0号独占
$physical = map($pid, $virtual);  // OS映射到真实位置
// 进程A和B的0x0000指向不同物理内存, 互不干扰
CODE],

            32 => ['文件的概念',
                '按名字打包存盘,不用管存哪个磁道。',
                <<<'CODE'
$f = fopen('简历.docx', 'w'); // 起名
fwrite($f, '内容');           // 读写
fclose($f);                   // 存哪由OS管
CODE],

            33 => ['输入/输出的概念',
                '数据进出电脑,系统统一管理。',
                <<<'CODE'
$data = fread($net, 1024);   // 从网络输入
fwrite($disk, $data);        // 输出到硬盘
CODE],

            34 => ['保护机制',
                '越界访问立即报错,进程互不破坏。',
                <<<'CODE'
if ($addr < $base || $addr > $limit) {
    die("段错误: 越界访问被OS拦下");
}
CODE],

            35 => ['shell 与命令解释器',
                '你输命令,shell 翻译给系统执行。',
                <<<'CODE'
while ($cmd = readline('$ ')) {
    system($cmd);            // 把你的命令转交系统执行
}
CODE],

            36 => ['本体论与重新研究',
                '把“进程、文件”等核心概念定义清楚。',
                <<<'CODE'
interface Process { public function run(): void; }
interface File    { public function read(): string; }
// 基础概念理清, 架构才不乱
CODE],

            37 => ['系统调用',
                '程序求系统办事的唯一正规途径(用户态→内核态)。',
                <<<'CODE'
$fd = fopen('a.txt', 'r');   // 底层触发 open 系统调用
// 此刻 CPU 从用户态切入内核态, 由内核去读硬盘
CODE],

            38 => ['用于进程管理的系统调用',
                'fork 创建、exec 换程序、wait 等子、exit 退出。',
                <<<'CODE'
$pid = pcntl_fork();              // 创建
if ($pid == 0) pcntl_exec('/bin/ls');  // 换成别的程序
else           pcntl_wait($status);    // 等子进程
CODE],

            39 => ['用于文件管理的系统调用',
                'open / read / write / close。',
                <<<'CODE'
$fd = fopen('log', 'a');     // open
fwrite($fd, "一行日志\n");    // write
fclose($fd);                 // close
CODE],

            40 => ['用于目录管理的系统调用',
                'mkdir / rmdir / rename 组织文件层级。',
                <<<'CODE'
mkdir('photos');             // 建目录
rename('photos', 'pics');    // 改名
rmdir('pics');               // 删目录
CODE],

            41 => ['各种系统调用',
                '改权限、改时间、挂载等杂项。',
                <<<'CODE'
chmod('a.txt', 0644);        // 改权限
touch('a.txt');              // 改时间戳
// mount('/dev/sdb', '/mnt'); 挂载磁盘
CODE],

            42 => ['Windows Win32 API',
                'Windows 上调 API,由它转交系统调用。',
                <<<'CODE'
// Windows 程序员调用 API, 而非直接系统调用
// CreateWindow(); ReadFile(); WriteFile();
$handle = win32_api_call('CreateFile', 'a.txt');
CODE],

            43 => ['单体系统结构',
                '所有功能挤在一个大内核,快但脆。',
                <<<'CODE'
$kernel = [fs(), driver(), scheduler(), memMgr()];  // 全塞一起
// 调用快; 但一个坏驱动可能拖崩整个系统
CODE],

            44 => ['层次式系统结构',
                '像盖楼分层,每层只跟相邻层打交道。',
                <<<'CODE'
$layers = ['硬件', '内存管理', '进程管理', 'IO', '用户'];
// 命令逐层下传, 清晰但有转手开销
CODE],

            45 => ['微内核',
                '内核只留核心,其它功能当服务跑。',
                <<<'CODE'
$kernel = [ipc(), scheduler()];         // 内核只留核心
$fs = startUserService('filesystem');   // 文件系统踢出去当服务
// 某服务崩了不连累内核
CODE],

            46 => ['客户端-服务器模式',
                '客户端发请求,服务器干活回结果。',
                <<<'CODE'
$req  = $client->send("要网页");
$resp = $server->handle($req);   // 服务器处理后返回
echo $resp;
CODE],

            47 => ['虚拟机',
                '软件造出“电脑里的电脑”,互不干扰。',
                <<<'CODE'
$vm = new VirtualMachine();
$vm->install('Linux');       // 真机里跑一套完整Linux
$vm->boot();                 // 关掉它, 真机毫发无损
CODE],

            48 => ['外核(Exokernel)',
                '内核只安全分配资源,用法交给程序自己。',
                <<<'CODE'
$disk = exokernel_alloc('disk', sectors: '1-100');
// 内核只说"这些扇区归你了"
// 至于怎么组织文件格式, 程序自己说了算
CODE],

            49 => ['公制单位',
                '注意存储 1024 与 1000 两种口径,别看错容量。',
                <<<'CODE'
$tb_vendor = 1000 ** 4;      // 商家: 1TB
$gb_real   = $tb_vendor / (1024 ** 3);
echo round($gb_real, 2);     // 931.32 GB (电脑显示)
CODE],
        ];

        foreach ($data as $no => [$title, $plain, $code]) {
            $this->topics[$no] = new Topic($no, $title, $plain, $code);
        }
    }

    public function renderAll(): void
    {
        $this->printHeader('现代操作系统 · 第一章《操作系统概论》大白话 + 代码例子');
        foreach ($this->topics as $t) $this->printTopic($t);
        $this->printFooter(count($this->topics));
    }

    public function renderOne(int $no): void
    {
        if (!isset($this->topics[$no])) {
            echo "⚠️  没有第 {$no} 条(本章 1~49)\n";
            return;
        }
        $this->printHeader("第 {$no} 条");
        $this->printTopic($this->topics[$no]);
    }

    public function search(string $kw): void
    {
        $hit = array_filter(
            $this->topics,
            fn(Topic $t) => mb_strpos($t->title, $kw) !== false
                         || mb_strpos($t->plain, $kw) !== false
                         || mb_strpos($t->code, $kw) !== false
        );
        if (!$hit) { echo "🔍 没找到包含“{$kw}”的条目\n"; return; }
        $this->printHeader("搜索“{$kw}”,命中 " . count($hit) . " 条");
        foreach ($hit as $t) $this->printTopic($t);
    }

    private function printHeader(string $title): void
    {
        echo "\n" . str_repeat('=', 62) . "\n  {$title}\n" . str_repeat('=', 62) . "\n";
    }

    private function printTopic(Topic $t): void
    {
        printf("\n【%02d】%s\n", $t->no, $t->title);
        echo "  ▷ 大白话:" . wordwrap_cn($t->plain, 36, "\n            ") . "\n";
        echo "  ▶ 代码例子:\n";
        foreach (explode("\n", $t->code) as $line) {
            echo "      | " . $line . "\n";
        }
    }

    private function printFooter(int $count): void
    {
        echo "\n" . str_repeat('-', 62) . "\n";
        echo "  共 {$count} 条,每条含“大白话 + PHP代码例子”。\n";
        echo str_repeat('-', 62) . "\n";
    }
}

/** 中文换行 */
function wordwrap_cn(string $text, int $width, string $break): string
{
    $len = mb_strlen($text);
    if ($len <= $width) return $text;
    $out = '';
    for ($i = 0; $i < $len; $i += $width) {
        $out .= mb_substr($text, $i, $width);
        if ($i + $width < $len) $out .= $break;
    }
    return $out;
}

// ===================== 入口 =====================
$book = new OsIntroBook();
$arg = $argv[1] ?? null;
if ($arg === null)            $book->renderAll();
elseif (ctype_digit($arg))    $book->renderOne((int) $arg);
else                          $book->search($arg);
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐