现代操作系统—原理与实现

37 阅读6分钟

现代操作系统—原理与实现---youkeit.xyz/14547/

经济复苏期技术护城河:吃透 OS 原理,求职议价权较行业均值翻倍

为什么操作系统原理是程序员的终极护城河?

在经济复苏期,技术岗位竞争加剧,掌握操作系统核心原理的程序员往往能获得比行业平均薪资高出50%-100%的offer。操作系统作为计算机科学的基石,深入理解其原理能让你:

  1. 写出更高效、更稳定的代码
  2. 快速定位和解决复杂系统问题
  3. 设计出更具扩展性的架构
  4. 在面试中展现深厚的技术底蕴

操作系统核心原理实战解析

1. 进程调度算法实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MAX_PROCESSES 10

typedef struct {
    int pid;
    int arrival_time;
    int burst_time;
    int remaining_time;
    int waiting_time;
    int turnaround_time;
    bool completed;
} Process;

// 先来先服务调度算法
void fcfs(Process processes[], int n) {
    int current_time = 0;
    for (int i = 0; i < n; i++) {
        if (current_time < processes[i].arrival_time) {
            current_time = processes[i].arrival_time;
        }
        processes[i].waiting_time = current_time - processes[i].arrival_time;
        processes[i].turnaround_time = processes[i].waiting_time + processes[i].burst_time;
        current_time += processes[i].burst_time;
    }
}

// 短作业优先调度算法
void sjf(Process processes[], int n) {
    int current_time = 0;
    int completed = 0;
    
    while (completed < n) {
        int shortest = -1;
        int shortest_time = __INT_MAX__;
        
        for (int i = 0; i < n; i++) {
            if (!processes[i].completed && 
                processes[i].arrival_time <= current_time && 
                processes[i].burst_time < shortest_time) {
                shortest = i;
                shortest_time = processes[i].burst_time;
            }
        }
        
        if (shortest == -1) {
            current_time++;
            continue;
        }
        
        processes[shortest].waiting_time = current_time - processes[shortest].arrival_time;
        processes[shortest].turnaround_time = processes[shortest].waiting_time + processes[shortest].burst_time;
        current_time += processes[shortest].burst_time;
        processes[shortest].completed = true;
        completed++;
    }
}

// 轮转调度算法
void round_robin(Process processes[], int n, int quantum) {
    int current_time = 0;
    int completed = 0;
    int remaining[MAX_PROCESSES];
    
    for (int i = 0; i < n; i++) {
        remaining[i] = processes[i].burst_time;
    }
    
    while (completed < n) {
        bool any_process_executed = false;
        
        for (int i = 0; i < n; i++) {
            if (remaining[i] > 0 && processes[i].arrival_time <= current_time) {
                any_process_executed = true;
                
                int execute_time = (remaining[i] > quantum) ? quantum : remaining[i];
                current_time += execute_time;
                remaining[i] -= execute_time;
                
                if (remaining[i] == 0) {
                    completed++;
                    processes[i].turnaround_time = current_time - processes[i].arrival_time;
                    processes[i].waiting_time = processes[i].turnaround_time - processes[i].burst_time;
                }
            }
        }
        
        if (!any_process_executed) {
            current_time++;
        }
    }
}

void print_results(Process processes[], int n) {
    printf("PID\tArrival\tBurst\tWaiting\tTurnaround\n");
    float avg_waiting = 0, avg_turnaround = 0;
    
    for (int i = 0; i < n; i++) {
        printf("%d\t%d\t%d\t%d\t%d\n", 
               processes[i].pid,
               processes[i].arrival_time,
               processes[i].burst_time,
               processes[i].waiting_time,
               processes[i].turnaround_time);
        
        avg_waiting += processes[i].waiting_time;
        avg_turnaround += processes[i].turnaround_time;
    }
    
    printf("\nAverage Waiting Time: %.2f\n", avg_waiting / n);
    printf("Average Turnaround Time: %.2f\n", avg_turnaround / n);
}

int main() {
    Process processes[] = {
        {1, 0, 6, 6, 0, 0, false},
        {2, 1, 8, 8, 0, 0, false},
        {3, 2, 7, 7, 0, 0, false},
        {4, 3, 3, 3, 0, 0, false}
    };
    int n = sizeof(processes) / sizeof(processes[0]);
    
    printf("FCFS Scheduling:\n");
    fcfs(processes, n);
    print_results(processes, n);
    
    // 重置进程状态
    for (int i = 0; i < n; i++) {
        processes[i].waiting_time = 0;
        processes[i].turnaround_time = 0;
        processes[i].completed = false;
    }
    
    printf("\nSJF Scheduling:\n");
    sjf(processes, n);
    print_results(processes, n);
    
    // 重置进程状态
    for (int i = 0; i < n; i++) {
        processes[i].waiting_time = 0;
        processes[i].turnaround_time = 0;
        processes[i].completed = false;
    }
    
    printf("\nRound Robin Scheduling (Quantum=4):\n");
    round_robin(processes, n, 4);
    print_results(processes, n);
    
    return 0;
}

2. 内存管理:简易内存分配器实现

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#define MEMORY_SIZE 1024  // 1KB内存

typedef struct block {
    size_t size;
    bool free;
    struct block *next;
} Block;

Block *free_list = NULL;

void initialize() {
    free_list = (Block *)malloc(MEMORY_SIZE);
    free_list->size = MEMORY_SIZE - sizeof(Block);
    free_list->free = true;
    free_list->next = NULL;
}

void split(Block *curr, size_t size) {
    Block *new_block = (Block *)((void *)curr + sizeof(Block) + size);
    new_block->size = curr->size - size - sizeof(Block);
    new_block->free = true;
    new_block->next = curr->next;
    
    curr->size = size;
    curr->free = false;
    curr->next = new_block;
}

void *my_malloc(size_t size) {
    if (!free_list) {
        initialize();
    }
    
    Block *curr = free_list;
    while (curr) {
        if (curr->free && curr->size >= size) {
            if (curr->size > size + sizeof(Block)) {
                split(curr, size);
            } else {
                curr->free = false;
            }
            return (void *)(curr + 1);
        }
        curr = curr->next;
    }
    return NULL;  // 内存不足
}

void merge() {
    Block *curr = free_list;
    while (curr && curr->next) {
        if (curr->free && curr->next->free) {
            curr->size += curr->next->size + sizeof(Block);
            curr->next = curr->next->next;
        } else {
            curr = curr->next;
        }
    }
}

void my_free(void *ptr) {
    if (!ptr) return;
    
    Block *block = (Block *)ptr - 1;
    block->free = true;
    merge();
}

void print_memory() {
    Block *curr = free_list;
    printf("Memory Layout:\n");
    while (curr) {
        printf("Block: %p | Size: %zu | Free: %s\n", 
               curr, curr->size, curr->free ? "Yes" : "No");
        curr = curr->next;
    }
    printf("\n");
}

int main() {
    initialize();
    
    printf("Initial memory:\n");
    print_memory();
    
    int *a = (int *)my_malloc(sizeof(int) * 100);  // 400 bytes
    printf("After allocating 400 bytes:\n");
    print_memory();
    
    char *b = (char *)my_malloc(sizeof(char) * 200);  // 200 bytes
    printf("After allocating 200 bytes:\n");
    print_memory();
    
    my_free(a);
    printf("After freeing first allocation:\n");
    print_memory();
    
    my_free(b);
    printf("After freeing all allocations:\n");
    print_memory();
    
    return 0;
}

3. 文件系统:简易文件系统实现

import os
import pickle

class FileSystem:
    def __init__(self, disk_file='disk.img'):
        self.disk_file = disk_file
        self.block_size = 512  # 512字节的块大小
        self.total_blocks = 1024  # 总共1024个块,约0.5MB
        self.free_blocks = set(range(self.total_blocks))
        self.inodes = {}  # 文件inode表
        self.root = {'/': {}}  # 根目录
        
        if os.path.exists(disk_file):
            self._load()
        else:
            self._format()
    
    def _format(self):
        # 初始化超级块
        self.superblock = {
            'block_size': self.block_size,
            'total_blocks': self.total_blocks,
            'free_blocks': self.free_blocks,
        }
        self._sync()
    
    def _sync(self):
        with open(self.disk_file, 'wb') as f:
            pickle.dump({
                'superblock': self.superblock,
                'inodes': self.inodes,
                'root': self.root
            }, f)
    
    def _load(self):
        with open(self.disk_file, 'rb') as f:
            data = pickle.load(f)
            self.superblock = data['superblock']
            self.inodes = data['inodes']
            self.root = data['root']
            self.free_blocks = set(self.superblock['free_blocks'])
    
    def _allocate_blocks(self, num_blocks):
        if len(self.free_blocks) < num_blocks:
            raise Exception("Not enough free blocks")
        
        allocated = []
        for _ in range(num_blocks):
            block = self.free_blocks.pop()
            allocated.append(block)
        
        self.superblock['free_blocks'] = list(self.free_blocks)
        self._sync()
        return allocated
    
    def _free_blocks(self, blocks):
        for block in blocks:
            self.free_blocks.add(block)
        self.superblock['free_blocks'] = list(self.free_blocks)
        self._sync()
    
    def create_file(self, path, content):
        # 计算需要的块数
        content_size = len(content)
        blocks_needed = (content_size + self.block_size - 1) // self.block_size
        
        # 分配块
        allocated_blocks = self._allocate_blocks(blocks_needed)
        
        # 创建inode
        inode_id = len(self.inodes) + 1
        self.inodes[inode_id] = {
            'size': content_size,
            'blocks': allocated_blocks,
            'type': 'file'
        }
        
        # 更新目录结构
        dirs = path.split('/')[:-1]
        filename = path.split('/')[-1]
        
        current_dir = self.root['/']
        for d in dirs:
            if d and d not in current_dir:
                current_dir[d] = {}
            if d:
                current_dir = current_dir[d]
        
        current_dir[filename] = inode_id
        
        # 写入数据
        with open(self.disk_file, 'ab') as f:
            for i, block in enumerate(allocated_blocks):
                start = i * self.block_size
                end = start + self.block_size
                block_data = content[start:end].ljust(self.block_size, '\0')
                f.seek(block * self.block_size)
                f.write(block_data.encode())
        
        self._sync()
        return inode_id
    
    def read_file(self, path):
        # 查找inode
        dirs = path.split('/')[:-1]
        filename = path.split('/')[-1]
        
        current_dir = self.root['/']
        for d in dirs:
            if d:
                current_dir = current_dir[d]
        
        inode_id = current_dir[filename]
        inode = self.inodes[inode_id]
        
        # 读取数据
        content = bytearray()
        with open(self.disk_file, 'rb') as f:
            for block in inode['blocks']:
                f.seek(block * self.block_size)
                content += f.read(self.block_size)
        
        return content[:inode['size']].decode()
    
    def delete_file(self, path):
        # 查找inode
        dirs = path.split('/')[:-1]
        filename = path.split('/')[-1]
        
        current_dir = self.root['/']
        for d in dirs:
            if d:
                current_dir = current_dir[d]
        
        inode_id = current_dir.pop(filename)
        inode = self.inodes.pop(inode_id)
        
        # 释放块
        self._free_blocks(inode['blocks'])
        self._sync()
    
    def mkdir(self, path):
        dirs = path.split('/')
        
        current_dir = self.root['/']
        for d in dirs:
            if d and d not in current_dir:
                current_dir[d] = {}
            if d:
                current_dir = current_dir[d]
        
        self._sync()
    
    def list_dir(self, path='/'):
        dirs = path.split('/') if path != '/' else []
        
        current_dir = self.root['/']
        for d in dirs:
            if d:
                current_dir = current_dir[d]
        
        return list(current_dir.keys())

# 使用示例
if __name__ == '__main__':
    fs = FileSystem()
    
    print("Creating /test directory...")
    fs.mkdir('/test')
    
    print("Creating /test/hello.txt...")
    fs.create_file('/test/hello.txt', 'Hello, World! This is a simple file system implementation.')
    
    print("Listing /test:")
    print(fs.list_dir('/test'))
    
    print("Reading /test/hello.txt:")
    print(fs.read_file('/test/hello.txt'))
    
    print("Deleting /test/hello.txt...")
    fs.delete_file('/test/hello.txt')
    
    print("Listing /test after deletion:")
    print(fs.list_dir('/test'))

操作系统知识如何转化为求职优势?

1. 面试高频考点

  • 进程与线程:区别、通信方式、同步机制
  • 内存管理:分页、分段、虚拟内存、页面置换算法
  • 文件系统:inode结构、文件存储方式、目录实现
  • I/O系统:DMA、缓冲、设备驱动
  • 死锁:条件、预防、避免、检测与恢复

2. 实战应用场景

  1. 高性能服务器开发:理解epoll/select底层实现
  2. 数据库优化:理解B+树索引与文件系统的结合
  3. 分布式系统:理解网络通信与进程通信的异同
  4. 嵌入式开发:直接操作硬件资源

3. 学习路径建议

  1. 基础理论:《现代操作系统》、《操作系统概念》
  2. 源码研究:Linux 0.11、xv6教学系统
  3. 实践项目:实现简易操作系统、内存分配器、文件系统
  4. 性能优化:使用perf、strace等工具分析系统调用

结语

在经济复苏期,技术深度而非广度将成为区分普通开发者和顶尖开发者的关键指标。操作系统原理作为计算机科学的"内功",掌握它不仅能让你的代码质量显著提升,还能在技术面试中展现出与众不同的深度思考能力。投资操作系统知识的学习,就是在构建自己最坚固的技术护城河。