[Python学习日记-84] 进程理论

[Python学习日记-84] 进程理论

简介

进程的概念

并发与并行的区别

进程并发的实现

简介

        进程理论是计算机科学中一种重要的概念,用来描述操作系统中执行的程序实例。在操作系统中,每个程序的执行被称为一个进程。进程理论研究进程的创建、调度、通信、同步和终止等方面的原理和方法。本篇我们将介绍进程的概念、进程的创建和终止,以及并发与并行的区别,并了解并发的实现。

进程的概念

一、什么是进程

        进程是计算机中正在运行的程序的实例,大白话说就是正在进行的一个过程或者说一个任务,而负责执行任务则是 CPU。

        每个进程都有自己独立的内存空间,包括代码、数据和堆栈等,使其能够独立运行并与其他进程隔离。操作系统通过管理进程来分配资源,确保它们能够有效地运行并与其他进程协同工作。在多任务系统中,多个进程可以同时运行,共享计算机的处理器和内存资源。

二、进程与程序的区别

        进程和程序是计算机领域中的两个重要概念,它们之间有一定的区别:

程序:程序是一组指令的集合,描述了在计算机上执行特定任务的步骤和逻辑。程序是静态的,它们通常存储在磁盘或内存中,并且不具有执行的状态。程序可以是源代码、可执行文件或脚本等形式。

进程:进程是程序在计算机中执行时的实例。当程序被加载到内存中,并被操作系统调度执行时,就会形成一个进程。每个进程都拥有独立的内存空间、堆栈和寄存器等资源,用于执行程序中的指令和处理数据。

        总的来说,程序仅仅只是一堆代码而已,而进程指的是程序的运行过程。

        举个例子,在一家有名的西餐厅中,厨师们正在为迎接顾客而做准备,他们有菜单中每道菜相应的食谱,厨房里有所需的原料(土豆、胡萝卜、牛肉、鸡肉等)。

        在这个比喻中:

  • 菜单中每道菜相应的食谱就是程序(即用适当形式描述的算法)
  • 厨师们就是处理器(即CPU)
  • 做菜用的各种原材料就是输入的数据
  • 进程就是厨师阅读食谱,取来各种原材料以及烹饪料理等一系列动作的总和

        餐厅开始营业了,顾客陆续进场,各项作业都井然有序的执行着,突然间一位顾客被鲜嫩多汁的牛排卡住了喉咙,厨师想了想,处理被卡住喉咙的顾客比做其他菜更加重要,于是厨师就记录下他照着食谱做到哪儿了(保存进程的当前状态),然后拿出一本急救手册,按照其中的指示进行海姆立克急救法对顾客进行急救。

        这里,我们看到处理机从一个进程(做菜)切换到另一个高优先级的进程(实施医疗救治),每个进程拥有各自的程序(食谱和急救手册)。当被食物卡住喉咙的顾客处理完之后,这位厨师又会回来继续从他离开时的那一步开始继续把菜做下去。

需要强调的是:同一个程序执行两次,那也是两个进程,例如,用 PoyPlayer(视频播放软件)打开两个视频,虽然都是同一个软件,但是一个播放的是哆啦A梦,另一个播放的是蜡笔小新。

三、同步\异步和阻塞\非阻塞

1、同步

        所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不会返回。按照这个定义,其实绝大多数函数都是同步调用。但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。

        举个例子:

  • multiprocessing.Pool 下的 apply(发起同步调用后,就在原地等着任务结束,根本不考虑任务是在计算还是在 I/O 阻塞,总之就是无脑地等任务结束,这十分容易造成死锁现象,实际编程中应该避免这种等待)
  • concurrent.futures.ProcessPoolExecutor().submit(func,).result()
  • concurrent.futures.ThreadPoolExecutor().submit(func,).result()

2、异步

        异步的概念和同步相对。当一个异步功能调用发出后,调用者不能立刻得到结果。当该异步功能完成后,通过状态、通知或回调来通知调用者。如果异步功能用状态来通知,那么调用者就需要每隔一定时间检查一次,效率就很低(有些初学多线程编程的人,总喜欢用一个循环去检查某个变量的值,这其实是一 种很严重的错误)。如果是使用通知的方式,效率则很高,因为异步功能几乎不需要做额外的操作。至于回调函数,其实和通知没太多区别。

        举个例子:

  • multiprocessing.Pool().apply_async()(发起异步调用后,并不会等待任务结束才返回,相反,会立即获取一个临时结果,该结果并不是最终的结果,可能是封装好的一个对象)
  • concurrent.futures.ProcessPoolExecutor(3).submit(func,)
  • concurrent.futures.ThreadPoolExecutor(3).submit(func,)

3、阻塞

        阻塞调用是指调用结果返回之前,当前线程会被挂起(例如,遇到 I/O 操作)。函数只有在得到结果之后才会将阻塞的线程激活。有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。
        举个例子:

  • 同步调用:apply 一个累计1亿次的任务,该调用会一直等待,直到任务返回结果为止,但并未阻塞住(即便是被抢走 CPU 的执行权限,那也是处于就绪态)
  • 阻塞调用:当 socket 工作在阻塞模式的时候,如果没有数据的情况下调用 recv 函数,则当前线程就会被挂起,直到有数据为止

4、非阻塞

        非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前也会立刻返回,同时该函数不会阻塞当前线程。

        总的来说,同步与异步针对的是函数(任务)的调用方式。同步就是当一个进程发起一个函数(任务)调用的时候,一直等到函数(任务)完成,而进程继续处于激活状态;异步情况下是当一个进程发起一个函数(任务)调用的时候,不会等函数返回,而是继续往下执行当,函数返回的时候通过状态、通知、事件等方式通知进程任务完成。阻塞与非阻塞针对的是进程或线程。阻塞是当请求不能满足的时候就将进程挂起;非阻塞则不会阻塞当前进程。

四、进程的创建与终止

1、创建

        但凡是硬件,都需要有操作系统去管理,只要有操作系统,就有进程的概念,就需要有创建进程的方式,一些操作系统只为一个应用程序设计,例如,电饭煲中的控制器,一旦电饭煲启动,电饭煲中的所有进程都会启动,并存在于存储当中。而对于通用系统(Windows、Linux、MacOS,之类会跑很多应用程序的),需要有系统运行过程中创建或撤销进程的能力,主要分为四种形式创建新的进程:

  1. 系统初始化(查看进程:例如,Linux 中用 ps 命令查看,Windows 中用任务管理器查看。前台进程负责与用户交互,后台运行的进程则与用户无关,而运行在后台并且只有在需要时才唤醒的进程,被称为守护进程,例如,电子邮件、Web 页面、新闻、打印等)
  2. 一个进程在运行过程中开启了子进程(例如,nginx 开启多进程、os.fork、subprocess.Popen 等)
  3. 用户的交互式请求,而创建一个新进程(例如,用户双击 QQ)
  4. 一个批处理作业的初始化(只在大型机的批处理系统中应用)

        无论上述的哪一种,新进程的创建都是由一个已经存在的进程执行了一个用于创建进程的系统调用而创建的,而在不同系统中调用的方法也各不相同:

  1. 在 Unix 中该系统调用的是 fork,fork 会先创建一个与父进程一模一样的副本,二者有相同的存储映像、同样的环境字符串和同样的打开文件(在 shell 解释器进程中,执行一个命令就会创建一个子进程)
  2. 在 Windows 中该系统调用的是 CreateProcess,CreateProcess 既处理进程的创建,也负责把正确的程序装入新进程中

        对于 Unix 和 Windows 创建的子进程有什么区别:

  1. 相同的是进程创建后,父进程和子进程有各自不同的地址空间(即多道技术要求物理层面实现进程之间内存的隔离),任何一个进程的在其地址空间中的修改都不会影响到另外一个进程
  2. 不同的是在 Unix 中,子进程的初始地址空间是父进程的一个副本,也就是说子进程和父进程是可以有只读的共享内存区的。但是对于 Windows 来说,从一开始父进程与子进程的地址空间就是不同的

2、终止

        对于进程的终止主要分为四种形式:

  1. 正常退出(自愿,如用户点击交互式页面的叉号,或程序执行完毕调用发起系统调用正常退出,在 Linux 中用 exit,在 Windows 中用 ExitProcess)
  2. 出错退出(自愿,执行命令 python a.py 时,命令中的 a.py 不存在)
  3. 严重错误(非自愿,执行非法指令,例如,引用不存在的内存地址、1/0 等,可以通过捕捉异常 try...except... 来规避)
  4. 被其他进程杀死(非自愿,例如,在 Linux 中使用 kill -9 杀死某个 pid)

五、进程的层次结构

        在操作系统中,进程的层次结构是指多个进程之间的父子关系组成的层次结构。通常情况下,一个操作系统会以树状结构来组织多个进程之间的关系。

        无论 Unix 还是 Windows,每个进程都有一个父进程(除了根进程,它是整个系统中的第一个进程),不同的是在 Unix 中所有的进程,都是以 init 进程为根,组成树形结构。父子进程共同组成一个进程组,这样当用户从键盘发出一个信号时,该信号被送给当前与键盘相关的进程组中的所有成员。

         在 Windows 中,没有进程层次的概念,所有的进程都是地位相同的,唯一类似于进程层次的暗示,是在创建进程时,父进程得到一个特别的令牌,称为句柄,该句柄可以用来控制子进程,但是父进程有权把该句柄传给其他子进程,这样就没有层次了。

六、进程的状态

        我们以一个 Unix 当中的命令为例

tail -f access.log |grep '404'

        在执行程序 tail 时,开启了一个子进程来执行程序 grep,两个进程之间基于管道“|”通讯开启了另外一个子进程,将 tail 的结果作为 grep 的输入。

        在这过程当中,进程 grep 在等待输入(即 I/O)时的状态被称为阻塞,此时 grep 命令是没有在运行的,在两种情况下会导致一个进程在逻辑上不能运行:

  1. 进程挂起是自身原因,遇到 I/O 阻塞,便要让出 CPU 让其他进程去执行,这样保证 CPU 一直在工作
  2. 与进程无关,是操作系统层面作出的操作,可能会因为一个进程占用时间过长,或者优先级等原因,进而调用其他的进程去使用 CPU

  • 运行:当一个进程在CPU上运行时(单处理机处于运行态的进程只有一个,多进程在 CPU 上交替运行)
  • 就绪:一个进程获得了除 CPU 外的一切所需资源,一旦得到处理机即可运行
  • 阻塞:阻塞也称等待或睡眠状态,一个进程正在等待某一事件发生(例如,请求 I/O、等待 I/O 完成等)而暂时停止运行,此时即使把 CPU 分配给进程也无法运行,故称进程处于阻塞状态

并发与并行的区别

        无论是并发还是并行,在用户看来都是“同时”运行的,不管是进程还是线程,都只是一个任务而已,真是干活的是 CPU,CPU 来做这些任务只能一个一个来,即同一时刻只能执行一个任务。

一、并发

        并发(Concurrency)是指在一个时间段内同时处理多个任务是伪并行,即看起来是同时运行。这些任务可以交替进行,每个任务都可能在不同的时间点被执行,但在任何时刻只有一个任务在被执行。在并发中,任务之间可能会互相影响或者依赖,需要通过调度算法来决定任务的执行顺序。单个 CPU 的情况下,可以利用多道技术来实现并发。

        举个例子:

  • 情人节约会:有一个海王他有三个女朋友,在情人节这天碰巧都要去同一个商场约会,那没办法你只能硬着头皮去了,我们把情人节这天和各个女朋友约会都看作是一个约会任务,这个海王被这三个任务共享,如果想要不出现修罗场的情况,那就要玩出并发恋爱的效果,具体操作应该是这样的,先跟“女友1”去看电影,看了一会说:“不好,我要拉肚子”,然后跑去跟“女友2”吃饭,吃了一会说:“那啥,我去趟洗手间”,然后跑去跟“女友3”开了个房,做了一回又跑回“女友1”哪里继续看电影,如此循环往复过完了情人节这天。

二、并行

        并行(Parallelism)是指在同一时刻同时执行多个任务。在并行中,多个任务同时在不同的处理器上或者不同的计算机上并行执行,每个任务都有自己的执行流程。并行可以显著提高计算效率,尤其是在处理大规模数据或者复杂计算任务时。

        举个例子:

  • 假设银行有四个柜台,现在来了六个客户都要办理业务,这样同一时间有四个任务被执行,假设分配给了柜台1、柜台2、柜台3、柜台4,这个时候所有柜台都占满了,客户5和客户6只能等着,一旦客户1遇到需要等待家人拿资料过来,就会中断当前服务,此时客户5就拿到柜台1的时间片去办理业务了,而客户1资料到了之后银行会重新调用他,可能会被分配到四个柜台的其中一个去继续处理之前的业务
  • 我们换个视角,从计算机的视角出发,四个柜台对应四个核,分别是 CPU1、CPU2、CPU3、CPU4,六个客户对应六个任务,这样同一时间有四个任务被执行,假设分别被分配给了 CPU1、CPU2、CPU3、CPU4,一旦任务1遇到 I/O 就被迫中断执行,此时任务5就拿到 CPU1 的时间片去执行(这就是单核下的多道技术,也就是说并行和多道技术并不冲突),而一旦任务1的 I/O 结束了,操作系统会重新调用它(要知道进程的调度、分配给哪个 CPU 运行,都是操作系统说了算,可能被分配给四个 CPU 中的任意一个去执行

         所有现代计算机经常会在同一时间做很多件事,即使是一台个人电脑(无论是单核还是多核),都可以同时运行多个任务(一个任务可以理解为一个进程),例如后台运行着360杀毒的同时打开着 QQ 在聊天,还打开了 PotPlay 播放电影。这些被同时运行的进程都需要被管理,这也说明了一个支持多进程的多道程序系统是多么至关重要。

        多道技术的回顾请查看这篇博客:操作系统的介绍

进程并发的实现

        进程并发的实现在于,硬件中断一个正在运行的进程,把此时进程运行的所有状态保存下来,为此操作系统需要维护一张表格来保存下终端的状态,这张表被称为进程表(Process Table),每个进程占用一个进程表项,这些表项被称为进程控制块

        该表存放了进程状态的重要信息:程序计数器、堆栈指针、内存分配状况、所有打开文件的状态、帐号和调度信息,以及进程由运行态转为就绪态或者阻塞态时必须保存的信息,从而保证该进程在再次启动时,就像从未被中断过一样。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/978761.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

信息系统的安全防护

文章目录 引言**1. 物理安全****2. 网络安全****3. 数据安全****4. 身份认证与访问控制****5. 应用安全****6. 日志与监控****7. 人员与管理制度****8. 其他安全措施****9. 安全防护框架**引言 从技术、管理和人员三个方面综合考虑,构建多层次、多维度的安全防护体系。 信息…

分布式主键生成服务

目录 一、使用线程安全的类——AtomicInteger或者AtomicLong 二、主键生成最简单写法(不推荐) 三、主键生成方法一:Long型id生成——雪花算法 四、主键生成方法二:流水号 (一)流水号概述 (二)添加配置 1.pom.xml 2.application.properties 3.创…

Linux 环境“从零”部署 MongoDB 6.0:mongosh 安装与数据操作全攻略

前提 完成linux平台部署MongoDB【部署教程】且完成mongosh的安装 由于本人使用的是6.0版本的MongoDB,新版本 MongoDB(尤其是 6.0 及以上版本)已经不再默认捆绑传统的 mongo shell,而改用新的 MongoDB Shell(mongosh&am…

使用Docker将ros1自定义消息通过rosjava_bootstrap生成jar包

文章目录 预准备环境rosjava_bootstrap坏消息好消息 环境安装docker安装rosjava_bootstrap仓库rosjava_center仓库修改rosjava_bootstrap代码拉取docker镜像放置自己的自定义消息 启动docker编译 预准备环境 rosjava_bootstrap rosjava_bootstrap是将自定义的ROS消息生成java…

RNN,LSTM,GRU三种循环网络的对比

1. 三种网络在准确率的对比 2. 三种网络在损失值的对比 3. 三种网络在计算时间的对比 4. RNN(传统循环神经网络) 主要特点: RNN 是最基础的循环神经网络,通过 递归 计算每个时间步的输出。在每个时间步,RNN 会将当前…

hackmyvm-hero

信息收集 ┌──(root㉿kali)-[/home/kali/Desktop/hackmyvm] └─# arp-scan -I eth1 192.168.56.0/24 Interface: eth1, type: EN10MB, MAC: 00:0c:29:34:da:f5, IPv4: 192.168.56.103 Starting arp-scan 1.10.0 with 256 hosts (https://github.com/royhills/arp-scan) 192…

纷析云:赋能企业财务数字化转型的开源解决方案

在企业数字化转型的浪潮中,财务管理的高效与安全成为关键。纷析云凭借其开源、安全、灵活的财务软件解决方案,为企业提供了一条理想的转型路径。 一、开源的力量:自主、安全、高效 纷析云的核心优势在于其100%开源的财务软件源码。这意味着…

异常c/c++

目录 1.c语言传统处理错误方式 1、终止程序 2、返回错误码 2.c异常概念 3.异常的使用 3.1异常的抛出与捕获 3.2异常安全(还有一些异常重新抛出) 3.3异常规范 4.自定义异常体系 5.c标准库的异常体系 6.异常优缺点 1、优点 2、缺点 7、补充 1.…

SAP-ABAP:使用ST05(SQL Trace)追踪结构字段来源的步骤

ST05 是 SAP 提供的 SQL 跟踪工具,可以记录程序运行期间所有数据库操作(如 SELECT、UPDATE、INSERT)。通过分析跟踪结果,可以精准定位程序中结构字段对应的数据库表。 步骤1:激活ST05跟踪 事务码 ST05 → 点击 Activa…

sklearn中的决策树-分类树:剪枝参数

剪枝参数 在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优,或者没有更多的特征可用为止。这样的决策树 往往会过拟合。为了让决策树有更好的泛化性,我们要对决策树进行剪枝。剪枝策略对决策树的影响巨大,正确的剪枝策…

安宝特科技 | Vuzix Z100智能眼镜+AugmentOS:重新定义AI可穿戴设备的未来——从操作系统到硬件生态,如何掀起无感智能革命?

一、AugmentOS:AI可穿戴的“操作系统革命” 2025年2月3日,Vuzix与AI人机交互团队Mentra联合推出的AugmentOS,被业内视为智能眼镜领域的“iOS时刻”。这款全球首个专为智能眼镜设计的通用操作系统,通过三大突破重新定义了AI可穿戴…

基于Rook的Ceph云原生存储部署与实践指南(上)

#作者:任少近 文章目录 1 Ceph环境准备2 rook部署ceph群集2.1 Rook 帮助地址2.2 安装ceph2.3 获取csi镜像2.4 Master参加到osd2.5 设置默认存储 3 Rook部署云原生RBD块存储3.1 部署storageclass资源3.2 部署WordPress使用RBD3.3 WordPress访问 4 Rook部署云原生RGW…

2月27(信息差)

🌍雷军超钟睒睒登顶中国首富 身家近4400亿元 🎄全球AI大混战升温!超越Sora的阿里万相大模型开源 家用显卡都能跑 ✨小米15 Ultra、小米SU7 Ultra定档2月27日 雷军宣布:向超高端进发 1.刚刚!DeepSeek硬核发布&#xff…

【Linux】文件系统深度解析:从基础到高级应用

🎬 个人主页:努力可抵万难 📖 个人专栏:《C语法》《Linux系列》《数据结构及算法》 ⛰️ 路虽远,行则将至 目录 📚一、引言:文件系统的核心作用与历史演进 📖1.文件系统的定义与功…

《Effective Objective-C》阅读笔记(中)

目录 接口与API设计 用前缀避免命名空间冲突 提供“全能初始化方法” 实现description方法 尽量使用不可变对象 使用清晰而协调的命名方式 方法命名 ​编辑类与协议命名 为私有方法名加前缀 理解OC错误模型 理解NSCopying协议 协议与分类 通过委托与数据源协议进行…

MongoDB—(一主、一从、一仲裁)副本集搭建

MongoDB集群介绍: MongoDB 副本集是由多个MongoDB实例组成的集群,其中包含一个主节点(Primary)和多个从节点(Secondary),用于提供数据冗余和高可用性。以下是搭建 MongoDB 副本集的详细步骤&am…

【实战 ES】实战 Elasticsearch:快速上手与深度实践-1.3.1单节点安装(Docker与手动部署)

👉 点击关注不迷路 👉 点击关注不迷路 👉 点击关注不迷路 文章大纲 10分钟快速部署Elasticsearch单节点环境1. 系统环境要求1.1 硬件配置推荐1.2 软件依赖 2. Docker部署方案2.1 部署流程2.2 参数说明2.3 性能优化建议 3. 手动部署方案3.1 安…

Rt-thread源码剖析(1)——内核对象

前言 该系列基于rtthread-nano的内核源码,来研究RTOS的底层逻辑,本文介绍RTT的内核对象,对于其他RTOS来说也可供参考,万变不离其宗,大家都是互相借鉴,实现不会差太多。 内核对象容器 首先要明确的一点是什…

html css js网页制作成品——HTML+CSS甜品店网页设计(5页)附源码

目录 一、👨‍🎓网站题目 二、✍️网站描述 三、📚网站介绍 四、🌐网站效果 五、🪓 代码实现 🧱HTML 六、🥇 如何让学习不再盲目 七、🎁更多干货 一、👨‍&#x1f…

Trae根据原型设计稿生成微信小程序密码输入框的踩坑记录

一、需求描述 最近经常使用Trae生成一些小组件和功能代码(对Trae赶兴趣的可以看之前的文章《TraeAi上手体验》),刚好在用uniapp开发微信小程序时需要开发一个输入密码的弹框组件,于是想用Trae来实现。原型设计稿如下:…