《现代体系结构上的UNIX系统:内核程序员的对称多处理和缓存技术(修订版)》——1.2 进程、程序和线程

简介: 程序(program)被定义为执行某项任务所需的指令和数据集。进程(process)则是程序加上其执行状态的组合,进程最少要包括所有变量的值、硬件状态(如程序计数器(PC)、寄存器、条件码等),以及地址空间的内容说明。简而言之,一个进程就是一个执行中的程序。

本节书摘来自异步社区《现代体系结构上的UNIX系统:内核程序员的对称多处理和缓存技术(修订版)》一书中的第1章,第1.2节,作者:【美】Curt Schimmel著,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.2 进程、程序和线程

程序(program)被定义为执行某项任务所需的指令和数据集。进程(process)则是程序加上其执行状态的组合,进程最少要包括所有变量的值、硬件状态(如程序计数器(PC)、寄存器、条件码等),以及地址空间的内容说明。简而言之,一个进程就是一个执行中的程序。

当一个用户请求运行某个程序的时候,系统就会创建一个新进程来包含该程序的执行。直到进程终止之前,它都存在于系统中,最后它不是自愿终止就是内核使它终止,要么就是用户请求它终止。进程还可以在一定程度上通过那些影响诸如进程的调度优先级的系统调用进行控制。

通过进程的抽象概念,内核就让程序有了它自己是在硬件上运行的假象。除非用户程序明确想要和系统中的其他程序以某种方式进行通信(有几种服务可以来完成这个任务),否则它们不需要关心自己与那些程序的交互作用。每个进程都获得了各自的虚拟地址空间(virtual address space),并且(在大多数实现上)按时间片来运行,于是多个进程可以共享硬件。系统上其他进程的存在性对于该用户程序是透明的。这使得开发新程序的工作更容易,也有助于确保程序的可移植性。

许多现代的UNIX系统提供了一种称为线程(thread)的机制。线程掌握了一个进程内一条执行流的状态。一个线程的状态最少要由硬件状态,往往还有一个栈构成。所有的UNIX进程内部都至少有一个控制线程(control thread),这个控制线程代表了程序的执行。对于所有的UNIX系统,无论是过去的还是现在的系统都是如此。支持线程的系统允许在一个进程内同时有多个控制线程。在这种情况下,每个线程都有其自己的硬件状态,但是所有的线程都在同一个地址空间中执行。在单处理器上,一次只能执行一个线程。在多处理器上,一个进程中的不同线程可以同时在不同的处理器上执行。线程的优点之一就是创建线程的开销要比创建进程的开销小,在一个进程内实现一组协调工作的线程要比实现一组协调工作的独立进程效率更高。一般而言,在进程内部执行的线程数量对于本书所涵盖的主题没有影响。因此,后面章节中只提及进程,它暗含了在进程内部执行的所有线程。

除了几处例外(下面会详细说明),所有的程序,不论是在用户级上还是在内核级上执行的,都出现在某个进程的上下文(context)内(大多数传统的UNIX内核实现都是如此,但是对于专门的实现则可能不同)。所有的用户程序都在它们自己的进程的上下文中运行。当这些用户进程通过系统调用请求内核服务的时候,实现该系统调用的内核代码继续在请求进程的进程上下文内执行。这就能让内核方便地访问进程的所有状态及其地址空间。它还提供了一种代表用户程序记录内核执行的当前状态的方式。例如,如果需要挂起一次系统调用的执行来等待I/O操作完成,那么内核有关系统调用处理的状态就被保存在进程中。

由于所有的系统活动,无论是在用户级的还是在内核级的,都发生在某个进程的上下文中,因此UNIX内核只调度进程的执行。当使用传统的分时调度(time-sharing scheduling)策略的时候,在用户级执行的进程可能被划分成任意数量的时间片,从而让所有的进程公平地共享CPU。在内核级执行的进程则不会被划分时间片。只有在当前的内核进程明确允许的情况下,才能切换到在内核级执行的另一个进程。

“所有的系统活动都发生在进程内部”这一规则的一种例外情况就是中断处理程序(interrupt handler)的执行。中断是由I/O设备在它们有状态信息要返回给操作系统的时候产生的。例如,状态信息可能包括一次I/O操作完成的信息。由于中断总是在任意时刻没有警告就发生了,所以它们对于进程的执行来说是异步的。当它们发生的时候,UNIX内核允许它们中断当前进程的执行。接着,系统执行中断处理程序,直到该程序完成,或者它被一次优先级更高的中断所打断为止。内核级进程如果愿意,它们有权屏蔽中断。之所以这样做,仅仅是为了保护进程级代码和中断处理程序代码所共享的数据结构的完整性。

这一规则的第二种例外情况则伴随流(stream)服务过程而出现。来自AT&T的UNIX实现SVR3(System V Release 3)中引入了流机制,它提供了一种网络协议实现的框架。虽然详细讨论流超出了本书的范围,但是这里要说明一点是,出于性能方面的原因,服务过程是在任何进程的上下文之外运行的,就像中断处理程序一样。

相关文章
|
14天前
|
并行计算 Linux
Linux内核中的线程和进程实现详解
了解进程和线程如何工作,可以帮助我们更好地编写程序,充分利用多核CPU,实现并行计算,提高系统的响应速度和计算效能。记住,适当平衡进程和线程的使用,既要拥有独立空间的'兄弟',也需要在'家庭'中分享和并行的成员。对于这个世界,现在,你应该有一个全新的认识。
119 67
|
9月前
|
安全 Python
告别低效编程!Python线程与进程并发技术详解,让你的代码飞起来!
【7月更文挑战第9天】Python并发编程提升效率:**理解并发与并行,线程借助`threading`模块处理IO密集型任务,受限于GIL;进程用`multiprocessing`实现并行,绕过GIL限制。示例展示线程和进程创建及同步。选择合适模型,注意线程安全,利用多核,优化性能,实现高效并发编程。
115 3
|
5月前
|
缓存 算法 Linux
Linux内核的心脏:深入理解进程调度器
本文探讨了Linux操作系统中至关重要的组成部分——进程调度器。通过分析其工作原理、调度算法以及在不同场景下的表现,揭示它是如何高效管理CPU资源,确保系统响应性和公平性的。本文旨在为读者提供一个清晰的视图,了解在多任务环境下,Linux是如何智能地分配处理器时间给各个进程的。
|
5月前
|
算法 Linux 定位技术
Linux内核中的进程调度算法解析####
【10月更文挑战第29天】 本文深入剖析了Linux操作系统的心脏——内核中至关重要的组成部分之一,即进程调度机制。不同于传统的摘要概述,我们将通过一段引人入胜的故事线来揭开进程调度算法的神秘面纱,展现其背后的精妙设计与复杂逻辑,让读者仿佛跟随一位虚拟的“进程侦探”,一步步探索Linux如何高效、公平地管理众多进程,确保系统资源的最优分配与利用。 ####
120 4
|
5月前
|
缓存 负载均衡 算法
Linux内核中的进程调度算法解析####
本文深入探讨了Linux操作系统核心组件之一——进程调度器,着重分析了其采用的CFS(完全公平调度器)算法。不同于传统摘要对研究背景、方法、结果和结论的概述,本文摘要将直接揭示CFS算法的核心优势及其在现代多核处理器环境下如何实现高效、公平的资源分配,同时简要提及该算法如何优化系统响应时间和吞吐量,为读者快速构建对Linux进程调度机制的认知框架。 ####
|
5月前
|
算法 调度
探索操作系统的心脏:内核与进程管理
【10月更文挑战第25天】在数字世界的复杂迷宫中,操作系统扮演着关键角色,如同人体中的心脏,维持着整个系统的生命力。本文将深入浅出地剖析操作系统的核心组件——内核,以及它如何通过进程管理来协调资源的分配和使用。我们将从内核的概念出发,探讨它在操作系统中的地位和作用,进而深入了解进程管理的机制,包括进程调度、状态转换和同步。此外,文章还将展示一些简单的代码示例,帮助读者更好地理解这些抽象概念。让我们一起跟随这篇文章,揭开操作系统神秘的面纱,理解它如何支撑起我们日常的数字生活。
|
7月前
|
算法 调度 Python
探索操作系统的内核——一个简单的进程调度示例
【9月更文挑战第17天】在这篇文章中,我们将深入探讨操作系统的核心组件之一——进程调度。通过一个简化版的代码示例,我们将了解进程调度的基本概念、目的和实现方式。无论你是初学者还是有一定基础的学习者,这篇文章都将帮助你更好地理解操作系统中进程调度的原理和实践。
|
6月前
|
网络协议 安全 Java
难懂,误点!将多线程技术应用于Python的异步事件循环
难懂,误点!将多线程技术应用于Python的异步事件循环
173 0
|
7月前
|
监控 Java
线程池中线程异常后:销毁还是复用?技术深度剖析
在并发编程中,线程池作为一种高效利用系统资源的工具,被广泛用于处理大量并发任务。然而,当线程池中的线程在执行任务时遇到异常,如何妥善处理这些异常线程成为了一个值得深入探讨的话题。本文将围绕“线程池中线程异常后:销毁还是复用?”这一主题,分享一些实践经验和理论思考。
229 3
|
8月前
|
调度 虚拟化 容器
探索操作系统的心脏:内核与进程管理
【8月更文挑战第28天】在数字世界的复杂迷宫中,操作系统扮演着关键角色。它如同一座桥梁,连接硬件与软件,确保一切顺畅运行。本文将深入剖析操作系统的核心——内核和进程管理,揭示它们如何协同工作,保障系统的稳定与高效。通过简化的比喻,我们将一探究竟,了解操作系统背后的神秘面纱。