📚 Operating Systems and Programming: Process, Memory, and Resource Management | 操作系统与编程:进程、内存与资源管理
An operating system is much more than a user interface – it is the foundational software layer that manages hardware resources and provides services that directly shape how programs are written, compiled, loaded, and executed. For A-Level programmers, understanding the interaction between code and the OS is essential to writing efficient, robust applications and to grasping the full execution model behind high-level languages. This article explores the key mechanisms through which an operating system enables programming, from process creation and scheduling to memory management, file I/O, and concurrency.
操作系统远不止是一个用户界面,它是管理硬件资源并提供服务的基础软件层,这些服务直接影响着程序的编写、编译、加载和执行方式。对于A-Level程序员来说,理解代码与操作系统之间的交互对于编写高效、健壮的应用程序以及掌握高级语言背后的完整执行模型至关重要。本文探讨了操作系统支持编程的关键机制,从进程创建与调度、内存管理到文件I/O和并发控制。
1. The Role of an Operating System in Programming | 操作系统在编程中的角色
The operating system acts as an intermediary between application software and the physical hardware. It abstracts hardware complexities, providing programmers with a consistent set of services – such as process creation, memory allocation, file access, and network communication – through system calls. Without this abstraction, every program would need to include hardware-specific drivers, making software development impractical. The OS also enforces protection and resource sharing among multiple running programs, ensuring that a bug in one application does not crash the entire system.
操作系统充当应用程序与物理硬件之间的中介。它抽象了硬件的复杂性,通过系统调用为程序员提供了一组统一的服务——如进程创建、内存分配、文件访问和网络通信。如果没有这种抽象,每个程序都需要包含特定于硬件的驱动程序,这将使软件开发变得不切实际。操作系统还在多个运行程序之间强制执行保护和资源共享,确保一个应用程序中的错误不会导致整个系统崩溃。
From a programmer’s perspective, the OS defines the execution environment. It determines how a program is loaded into memory, how it is scheduled on the CPU, and how it interacts with I/O devices. Understanding these mechanisms allows developers to write code that is better optimised for the underlying platform, to handle errors more gracefully, and to use system resources responsibly. For example, knowledge of how the OS manages heap memory can help reduce memory leaks and fragmentation.
从程序员的角度看,操作系统定义了执行环境。它决定了程序如何加载到内存中、如何在CPU上调度以及如何与I/O设备交互。理解这些机制可以让开发者编写出更好地针对底层平台优化的代码,更优雅地处理错误,并负责任地使用系统资源。例如,了解操作系统如何管理堆内存有助于减少内存泄漏和碎片化。
2. From Source Code to Process Execution | 从源代码到进程执行
When a programmer writes source code in a high-level language, the path to a running process involves several stages: preprocessing, compilation, assembly, and linking. The final output is an executable file stored on disk. When the user runs the program, the operating system’s loader reads the executable file, creates a new process, allocates a virtual address space, and loads the code and static data into memory. The OS then initialises the process control block (PCB) and places the process in the ready queue for scheduling. This transformation from a static file to a dynamic entity is entirely managed by the OS.
当程序员用高级语言编写源代码时,通往运行进程的路径涉及多个阶段:预处理、编译、汇编和链接。最终输出是存储在磁盘上的可执行文件。当用户运行该程序时,操作系统的加载器读取可执行文件,创建一个新进程,分配虚拟地址空间,并将代码和静态数据加载到内存中。然后操作系统初始化进程控制块(PCB),并将该进程放入就绪队列等待调度。这种从静态文件到动态实体的转变完全由操作系统管理。
A process is not the same as a program. A program is a passive set of instructions on disk; a process is an active instance with its own memory space, CPU registers, open file descriptors, and one or more threads of execution. The OS maintains a process table to keep track of all active processes, storing context information such as the program counter, stack pointer, and priority. When context switching occurs, the OS saves the state of the currently running process and restores the state of the next process, enabling multitasking.
进程与程序不同。程序是磁盘上的一组被动指令;而进程是一个活跃的实例,拥有自己的内存空间、CPU寄存器、打开的文件描述符以及一个或多个执行线程。操作系统维护一个进程表来跟踪所有活动进程,存储诸如程序计数器、堆栈指针和优先级等上下文信息。当发生上下文切换时,操作系统保存当前运行进程的状态并恢复下一个进程的状态,从而实现多任务处理。
3. System Calls: Bridging User Programs and the Kernel | 系统调用:连接用户程序与内核
User programs run in unprivileged mode (user mode) and cannot directly access hardware or critical kernel data structures. To request services such as reading a file, creating a new process, or allocating memory, the program invokes a system call. A system call is a controlled mechanism that switches the processor from user mode to kernel mode, executes the requested operation inside the kernel, and returns the result. Examples in C-like languages include open(), read(), fork(), and mmap().
用户程序在非特权模式(用户模式)下运行,不能直接访问硬件或关键的内核数据结构。为了请求诸如读取文件、创建新进程或分配内存等服务,程序会调用系统调用。系统调用是一种受控机制,它将处理器从用户模式切换到内核模式,在内核中执行请求的操作,然后返回结果。类C语言中的例子包括open()、read()、fork()和mmap()。
From a pedagogical perspective, system calls illustrate the separation of policy and mechanism. The programmer decides what to do (policy) by writing code that invokes a system call, but the OS decides how it is done (mechanism) by implementing the kernel routine. This design keeps the kernel stable and secure while giving programmers a stable interface. In an A-Level context, tracing system calls—using tools like strace—can help students understand the hidden layers beneath their programs.
从教学角度来看,系统调用体现了策略与机制的分离。程序员通过编写调用系统调用的代码来决定做什么(策略),而操作系统通过实现内核例程来决定如何做(机制)。这种设计保持了内核的稳定和安全,同时为程序员提供了稳定的接口。在A-Level语境中,使用诸如strace这样的工具跟踪系统调用,可以帮助学生理解程序之下的隐藏层。
| System Call Category | Example | Purpose |
|---|---|---|
| Process Control | fork(), exec(), exit() | Create, replace, and terminate processes |
| File Management | open(), read(), write(), close() | Open, read, write, and close files |
| Device Management | ioctl() | Control device parameters |
| Memory Management | mmap(), brk() | Map memory or adjust heap |
系统调用分类表。系统调用类别:进程控制、文件管理、设备管理、内存管理。
4. Process Scheduling and Its Impact on Program Performance | 进程调度及其对程序性能的影响
The OS scheduler decides which process runs on the CPU at any given time. This is critical because a single-core CPU can only execute one thread at a time. Scheduling algorithms balance fairness, throughput, response time, and CPU utilisation. Common algorithms include First-Come First-Served (FCFS), Shortest Job Next (SJN), Round Robin (RR), and Multilevel Feedback Queue. Programmers who understand scheduling can design applications that yield the CPU voluntarily, use appropriate sleep intervals, or assign thread priorities to improve responsiveness.
操作系统调度器决定在任何给定时刻哪个进程在CPU上运行。这一点至关重要,因为单核CPU一次只能执行一个线程。调度算法在公平性、吞吐量、响应时间和CPU利用率之间取得平衡。常见的算法包括先来先服务(FCFS)、最短作业优先(SJN)、轮转法(RR)和多级反馈队列。了解调度的程序员可以设计出能够自愿放弃CPU、使用适当的休眠间隔或分配线程优先级以提高响应性的应用程序。
For example, a CPU-bound computation that runs for minutes without yielding will monopolise the processor under FCFS, but under Round Robin it will be preempted periodically, allowing interactive tasks to remain responsive. In an A-Level programming project, if a student writes a long loop without any I/O or delay, the user interface may freeze. Understanding that the OS preempts based on time slices helps explain why inserting a small sleep or using an event loop keeps the program responsive.
例如,在FCFS下,一个持续运行数分钟而不让出CPU的计算密集型任务会独占处理器,但在轮转法下它会被周期性地抢占,从而使交互式任务保持响应。在A-Level编程项目中,如果学生编写了一个没有任何I/O或延迟的长循环,用户界面可能会冻结。理解操作系统基于时间片进行抢占有助于解释为什么插入一个小的休眠或使用事件循环可以保持程序的响应性。
The context switching overhead is also relevant: excessive switching wastes CPU cycles. A Programmer who creates many active threads may experience a degradation in performance due to the scheduler spending more time switching than doing useful work. Therefore, a well-designed program balances parallelism with the scheduling granularity of the target OS.
上下文切换的开销也与之相关:过多的切换会浪费CPU周期。如果程序员创建了许多活跃线程,则可能会因为调度器花在切换上的时间多于做有用工作而导致性能下降。因此,一个设计良好的程序需要在并行性与目标操作系统的调度粒度之间取得平衡。
5. Memory Management: Virtual Memory and Address Spaces | 内存管理:虚拟内存与地址空间
Modern operating systems use virtual memory to give each process the illusion of having its own contiguous, isolated memory space. The CPU’s memory management unit (MMU) translates virtual addresses to physical addresses using page tables. This translation allows the OS to load programs anywhere in physical RAM, to protect processes from one another, and to implement paging to disk when memory is overcommitted. For a programmer, virtual memory means that the addresses seen in a debugger are not physical RAM locations but virtual addresses managed by the OS.
现代操作系统使用虚拟内存,让每个进程产生拥有自己连续、隔离内存空间的错觉。CPU的内存管理单元(MMU)使用页表将虚拟地址转换为物理地址。这种转换允许操作系统将程序加载到物理RAM的任何位置,保护进程彼此隔离,并在内存超额使用时实现页面交换到磁盘。对于程序员来说,虚拟内存意味着在调试器中看到的地址并不是物理RAM位置,而是由操作系统管理的虚拟地址。
When a program accesses an address that has been swapped to disk, a page fault occurs. The OS handles it by loading the required page from disk into a free frame, updating the page table, and resuming the program. From the programmer’s perspective, this mechanism is transparent, but it has performance implications: excessive page faults, known as thrashing, can grind the system to a halt. Programmers who work with large data sets should be aware of the memory hierarchy and design locality-friendly access patterns to minimise page faults.
当程序访问一个已被交换到磁盘的地址时,会发生缺页中断。操作系统通过将所需页面从磁盘加载到空闲帧中、更新页表并恢复程序来加以处理。从程序员的角度看,这种机制是透明的,但它对性能有影响:过多的缺页中断(称为颠簸)会使系统陷入停滞。处理大型数据集的程序员应该了解内存层次结构,并设计有利于局部性的访问模式以减少缺页中断。
Virtual Address = Page Number + Offset; Physical Address = Frame Number + Offset
虚拟地址 = 页号 + 偏移量;物理地址 = 帧号 + 偏移量
Dynamic memory allocation via functions like malloc() in C or new in C++/Java relies on the OS’s heap management. The kernel allocates large chunks of memory to the process via the brk() or mmap() system calls, and the runtime library manages these chunks to service smaller requests. Understanding this two-level allocation helps prevent memory fragmentation and explains why free() does not necessarily return memory to the OS immediately.
通过C语言中的malloc()或C++/Java中的new等函数进行的动态内存分配依赖于操作系统的堆管理。内核通过brk()或mmap()系统调用向进程分配大块内存,运行时库管理这些块以服务于更小的请求。理解这种两级分配有助于防止内存碎片化,并解释了为什么free()不一定立即将内存归还给操作系统。
6. File Systems and I/O Operations in Programs | 文件系统与程序中的I/O操作
File systems provide an abstraction for persistent storage, allowing programs to create, read, write, and delete files using a consistent naming hierarchy. The OS translates these logical operations into block-level reads and writes on the storage device. For a programmer, file I/O is performed through system calls wrapped in standard library functions such as fopen(), fread(), fwrite(), and fclose() in C, or through stream classes in higher-level languages. The OS buffers these operations to improve performance, which is why data might not appear immediately on disk unless flushed or synced.
文件系统为持久存储提供了一种抽象,允许程序使用一致的命名层次结构创建、读取、写入和删除文件。操作系统将这些逻辑操作转换为存储设备上的块级读写。对于程序员来说,文件I/O是通过包装在标准库函数中的系统调用来执行的,例如C语言中的fopen()、fread()、fwrite()和fclose(),或者通过高级语言中的流类来执行。操作系统会缓存这些操作以提高性能,这就是为什么除非刷新或同步,数据可能不会立即出现在磁盘上。
The OS also enforces access permissions, managed via access control lists (ACLs) or Unix-style permission bits. A program must possess the appropriate read, write, or execute permissions to perform operations on a file. Attempting to open a file without sufficient permissions results in an error, which the programmer must handle gracefully. In an A-Level project, robust error handling around file operations is a mark of good design and demonstrates an understanding of the OS security layer.
操作系统还通过访问控制列表(ACL)或Unix风格的权限位来强制执行访问权限。程序必须拥有适当的读、写或执行权限才能对文件进行操作。试图在没有足够权限的情况下打开文件会导致错误,程序员必须优雅地处理该错误。在A-Level项目中,围绕文件操作的健壮错误处理是良好设计的标志,并体现了对操作系统安全层的理解。
Moreover, the OS maintains a table of open file descriptors (or handles) for each process. When a program opens a file, it receives a small integer identifier that is used for subsequent operations. Standard input (0), standard output (1), and standard error (2) are automatically opened for every process, which is the foundation of input/output redirection and piping in shell programming.
此外,操作系统为每个进程维护一个打开文件描述符(或句柄)表。当程序打开一个文件时,会收到一个小整数标识符,用于后续操作。标准输入(0)、标准输出(1)和标准错误(2)会自动为每个进程打开,这是shell编程中输入/输出重定向和管道的基础。
7. Concurrency and Synchronisation in Programming | 编程中的并发与同步
Concurrency allows multiple tasks to make progress within a single program by interleaving their execution. The OS supports this through threads, which share the same address space but have separate execution contexts. A programmer can create threads using APIs such as pthread_create() in POSIX systems or std::thread in C++11. However, shared data access introduces race conditions, which can lead to non-deterministic bugs. The OS provides synchronisation primitives—mutexes, semaphores, condition variables—that help programmers coordinate thread execution.
并行使多个任务通过交替执行在单个程序中取得进展成为可能。操作系统通过线程来支持这一点,线程共享相同的地址空间但拥有独立的执行上下文。程序员可以使用API创建线程,例如POSIX系统中的pthread_create()或C++11中的std::thread。然而,共享数据访问会引入竞态条件,这可能导致非确定性的错误。操作系统提供了同步原语——互斥锁、信号量、条件变量——帮助程序员协调线程执行。
A mutex ensures mutual exclusion: only one thread can hold the lock at a time. Semaphores generalise this concept by allowing a fixed number of threads to access a resource concurrently. Condition variables enable threads to wait until a particular condition becomes true, which is essential for producer-consumer patterns. At the OS level, these primitives are often implemented using atomic operations and kernel-supported wait queues; understanding their implementation helps programmers avoid deadlocks and starvation.
互斥锁确保互斥:一次只能有一个线程持有锁。信号量通过允许固定数量的线程同时访问资源来推广这一概念。条件变量使线程可以等待直到某个特定条件为真,这对于生产者-消费者模式至关重要。在操作系统层面,这些原语通常使用原子操作和内核支持的等待队列来实现;理解其实现有助于程序员避免死锁和饥饿。
For A-Level students, writing a multithreaded program and using mutexes to protect a shared counter is a common practical exercise. Observing the incorrect output without synchronisation and the correct output with proper locks demonstrates the critical role the OS and hardware play in maintaining memory consistency. It also illustrates the performance cost of locking, as contention can serialise execution.
对于A-Level学生来说,编写一个多线程程序并使用互斥锁保护共享计数器是一项常见的实践练习。观察无同步时的错误输出和有适当锁时的正确输出,展示了操作系统和硬件在维护内存一致性方面所起的关键作用。这也说明了锁定的性能成本,因为竞争会串行化执行。
8. Deadlocks: Detection, Prevention and Avoidance | 死锁:检测、预防与避免
A deadlock occurs when two or more processes are each waiting for a resource held by another, creating a circular dependency that prevents all of them from proceeding. The four necessary conditions for deadlock are mutual exclusion, hold and wait, no preemption, and circular wait. The OS can address deadlocks through prevention (breaking one of the conditions), avoidance (dynamically checking for safe states, e.g., Banker’s algorithm), or detection and recovery (killing processes or revoking resources).
当两个或多个进程彼此等待对方持有的资源,形成一个循环依赖,导致所有进程都无法继续时,就会发生死锁。死锁的四个必要条件为互斥、持有并等待、不可抢占和循环等待。操作系统可以通过预防(打破其中一个条件)、避免(动态检查安全状态,例如银行家算法)或检测与恢复(终止进程或撤销资源)来处理死锁。
Programmers writing concurrent applications must be mindful of deadlock risks. For example, if thread A acquires lock L1 and then tries to acquire lock L2, while thread B acquires L2 and then tries to acquire L1, they deadlock. To prevent this, a common strategy is to enforce a consistent lock ordering or to use try-lock patterns with timeouts. The OS provides tools such as lockdep in the Linux kernel to detect potential deadlock patterns during development.
编写并发应用程序的程序员必须注意死锁风险。例如,如果线程A获取锁L1然后试图获取锁L2,而线程B获取L2然后试图获取L1,它们就会死锁。为防止这种情况,常见策略是强制执行一致的锁顺序,或使用带超时的尝试锁定模式。操作系统提供诸如Linux内核中的lockdep等工具,用于在开发过程中检测潜在的死锁模式。
In an A-Level context, simulating a deadlock scenario with two threads and two resources, then resolving it by reordering locks, provides a tangible understanding of this OS concept. The exercise reinforces the importance of design-level thinking about resource management rather than relying solely on runtime fixes.
在A-Level语境中,用两个线程和两个资源模拟一个死锁场景,然后通过重新排序锁来解决,可以提供对这一操作系统概念的具体理解。该练习强化了在设计层面对资源管理进行思考的重要性,而不是仅仅依赖运行时修复。
9. Linking and Loading: Static vs. Dynamic Libraries | 链接与加载:静态库与动态库
After compilation, object files are combined into a single executable by a linker. The linking process can be static or dynamic. With static linking, library code is copied directly into the final executable, making it self-contained but larger. With dynamic linking, the executable contains references to shared library files (.so on Linux, .dll on Windows) that are resolved by the OS loader at load time or at runtime. The OS must manage these shared libraries, loading them into memory once and mapping them into the address spaces of multiple processes to save RAM.
编译后,链接器将目标文件组合成一个可执行文件。链接过程可以是静态的或动态的。通过静态链接,库代码被直接复制到最终的可执行文件中,使其自成一体但体积更大。通过动态链接,可执行文件包含对共享库文件(Linux上为.so,Windows上为.dll)的引用,这些引用由操作系统加载器在加载时或运行时解析。操作系统必须管理这些共享库,将它们加载到内存一次并映射到多个进程的地址空间中以节省RAM。
For a programmer, dynamic linking offers flexibility: a library can be updated without recompiling the application. However, it also introduces versioning dependencies and the risk of ‘DLL hell’ if incompatible versions coexist. The OS resolves symbols using a search path (e.g., LD_LIBRARY_PATH on Linux) and maintains a reference count for each shared library; the library is unloaded when no process references it. Understanding this process helps developers diagnose linking errors and design more portable applications.
对于程序员来说,动态链接提供了灵活性:可以在不重新编译应用程序的情况下更新库。然而,它也引入了版本依赖以及如果存在不兼容版本时出现“DLL地狱”的风险。操作系统使用搜索路径解析符号(例如Linux上的LD_LIBRARY_PATH),并维护每个共享库的引用计数;当没有进程引用该库时,它会被卸载。理解这一过程有助于开发人员诊断链接错误并设计更具可移植性的应用程序。
In an A-Level project, choosing between static and dynamic linking involves trade-offs. A static executable is easier to distribute but consumes more disk and memory. A dynamic executable is smaller but requires the target system to have the correct runtime libraries installed. The OS’s role in managing shared library loading is transparent to most users but crucial for system stability.
在A-Level项目中,在静态和动态链接之间做出选择需要权衡利弊。静态可执行文件更易于分发,但会消耗更多的磁盘和内存。动态可执行文件更小,但要求目标系统安装正确的运行时库。操作系统在管理共享库加载方面的作用对大多数用户是透明的,但对系统稳定性至关重要。
10. Interrupts and Exception Handling at the OS Level | 中断与异常处理在操作系统层面
Interrupts and exceptions are mechanisms by which the hardware notifies the processor about events that need immediate attention. An interrupt is typically generated by an I/O device (e.g., a keyboard press or disk completion), while an exception is a synchronous event caused by program execution errors such as division by zero, invalid memory access, or a system call. The OS installs an Interrupt Descriptor Table (IDT) that maps each interrupt number to a handler routine. When an interrupt occurs, the CPU saves the current execution context and transfers control to the appropriate handler, running in kernel mode.
中断和异常是硬件通知处理器需要立即关注的事件的机制。中断通常由I/O设备产生(例如键盘按键或磁盘完成),而异常是由程序执行错误引起的同步事件,如除零、无效内存访问或系统调用。操作系统安装一个中断描述符表(IDT),将每个中断号映射到一个处理程序。当中断发生时,CPU保存当前执行上下文并将控制权转移给相应的处理程序,在内核模式下运行。
For a programmer, interrupts are largely invisible but have profound implications. For example, writing a tight, non-blocking I/O polling loop would be inefficient; instead, the OS allows a program to sleep until an interrupt signals that data is ready. This interrupt-driven model enables concurrent I/O and efficient CPU usage. Exceptions, on the other hand, are directly visible: a segmentation fault (SIGSEGV) delivered to a process is the OS’s way of reporting an invalid memory access. Handling signals in code allows programs to clean up resources before terminating.
对于程序员来说,中断在很大程度上是不可见的,但有着深远的影响。例如,编写一个紧凑的非阻塞I/O轮询循环将是低效的;相反,操作系统允许程序休眠,直到中断信号表明数据就绪。这种中断驱动模型实现了并发I/O和高效的CPU使用。另一方面,异常是直接可见的:传递给进程的段错误(SIGSEGV)是操作系统报告无效内存访问的方式。在代码中处理信号允许程序在终止之前清理资源。
In A-Level Computer Science, understanding the interrupt cycle helps explain how a CPU can respond to external events without constant polling. It also clarifies the transition between user and kernel mode, which is fundamental to system security and stability.
在A-Level计算机科学中,理解中断循环有助于解释CPU如何在不持续轮询的情况下响应外部事件。它还阐明了用户模式和内核模式之间的转换,这是系统安全性和稳定性的基础。
11. Virtualisation and Containers: Modern Programming Environments | 虚拟化与容器:现代编程环境
Virtualisation allows a single physical machine to run multiple isolated operating system instances, each with its own virtual hardware. A hypervisor, such as KVM or VMware, manages these virtual machines (VMs), while the OS inside each VM behaves as if it controls real hardware. From a programming perspective, VMs enable cross-platform development and testing without needing separate physical machines. The OS also supports containerisation, where multiple isolated user-space instances (containers) share the same kernel but have separate namespaces for processes, networking, and file systems.
虚拟化允许单台物理机器运行多个隔离的操作系统实例,每个实例拥有自己的虚拟硬件。虚拟机管理程序(如KVM或VMware)管理这些虚拟机(VM),而每个虚拟机内部的操作系统就好像控制着真实硬件一样运行。从编程的角度来看,虚拟机使得跨平台开发和测试成为可能,而无需单独的物理机器。操作系统还支持容器化,即多个隔离的用户空间实例(容器)共享同一个内核,但在进程、网络和文件系统方面拥有独立的命名空间。
Containers, popularised by Docker, are lightweight because they avoid the overhead of emulating entire hardware stacks. The OS kernel isolates containers using control groups (cgroups) to limit resource usage and namespaces to provide isolation. For A-Level programmers, deploying an application inside a container ensures that the runtime environment is consistent across development, testing, and production, reducing ‘it works on my machine’ problems. Understanding how the OS provides these isolation mechanisms deepens appreciation for kernel design.
由Docker推广的容器是轻量级的,因为它们避免了模拟整个硬件栈的开销。操作系统内核使用控制组(cgroups)限制资源使用,并使用命名空间提供隔离。对于A-Level程序员来说,在容器内部署应用程序可以确保运行时环境在开发、测试和生产中保持一致,减少“在我机器上可以运行”的问题。理解操作系统如何提供这些隔离机制可以加深对内核设计的认识。
12. Security and Protection Mechanisms for Programs | 程序的安全与保护机制
Operating systems enforce security boundaries that protect programs from one another and the kernel from malicious code. User and group IDs, file permissions, process isolation, and memory protection are fundamental. When a program runs, it operates with the privileges of its owner. The OS enforces that a process cannot directly access memory belonging to another process or to the kernel. If a program attempts an illegal operation, the OS sends a signal (e.g., SIGSEGV) and may terminate it. This protection is built on hardware features such as privilege levels and the MMU.
操作系统强制执行安全边界,以保护程序彼此之间以及内核免受恶意代码的侵害。用户和组ID、文件权限、进程隔离和内存保护是基础。当程序运行时,它以其所有者的权限运行。操作系统强制规定一个进程不能直接访问属于另一个进程或内核的内存。如果程序尝试非法操作,操作系统会发送一个信号(例如SIGSEGV),并可能终止它。这种保护建立在诸如特权级别和MMU等硬件特性之上。
From a programmer’s perspective, security affects how programs are written. For instance, a setuid program in Unix runs with the privileges of its owner rather than the user who invokes it. This mechanism allows programs like passwd to modify the password file, but it must be carefully written to avoid privilege escalation attacks. Input validation, proper use of system calls, and avoiding buffer overflows are programming practices that work in tandem with OS protections to create secure software.
从程序员的角度来看,安全性影响程序的编写方式。例如,Unix中的setuid程序以其所有者的权限运行,而不是以调用它的用户权限运行。这种机制允许诸如passwd之类的程序修改密码文件,但必须仔细编写以避免权限提升攻击。输入验证、正确使用系统调用以及避免缓冲区溢出是与操作系统保护协同工作以创建安全软件的编程实践。
Modern OS features such as Address Space Layout Randomisation (ASLR), Data Execution Prevention (DEP), and stack canaries are automatic defences that make exploiting vulnerabilities harder. Programmers should understand that these exist and that crafting exploits in a controlled environment for educational purposes (ethical hacking) illuminates the depth of OS-level defence mechanisms.
现代操作系统特性如地址空间布局随机化(ASLR)、数据执行保护(DEP)和堆栈金丝雀是自动
Published by TutorHao | A-Level 编程 Revision Series | aleveler.com
更多咨询请联系16621398022(同微信)
屏轩国际教育cambridge primary/secondary checkpoint, cat4, ukiset,ukcat,igcse,alevel,PAT,STEP,MAT, ibdp,ap,ssat,sat,sat2课程辅导,国外大学本科硕士研究生博士课程论文辅导