进程概念【linux】

进程基础

在学习进程之前,首先要有一定的计算机硬件和软件基础。

硬件基础:冯·诺依曼体系结构

如图,是计算机在硬件上的体系结构。 

下面举出一些常见的输入输出设备(有些设备只作输出设备,或者只作输入设备;而有些设备既能作为输出设备,又能作为输入设备)

输入设备:话筒、摄像头、键盘、网卡、磁盘,鼠标等等

输出设备:声卡、显卡、网卡、磁盘、显示器,打印机等等

这些设备连接在一起的目的:设备之间的数据流动。本质是设备之间频繁的数据拷贝!所以说,对数据进行拷贝的整体速度,是决定计算机效率的重要指标

经典场景:程序在运行的时候,必须把程序先加载到内存。

程序文件里都是指令和数据,这些指令和数据最终是要让 CPU 来执行的,而程序文件在生成后会存储在磁盘中,磁盘中的文件要先加载到内存,才能和 CPU 进行交互。所以,程序在运行的时候,必须先将程序加载到内存。

软件基础:操作系统

操作系统是计算机上一个进行软硬件资源管理的软件,同时它也是计算机开机同时第一个被加载的软件,它可以为用户提供一个稳定、高效、安全的运行环境

管理:根据数据做决策(操作系统)

被管理:执行管理者的决策(软硬件)

计算机对数据管理的建模:先将堆数据的管理场景转化为对特定数据结构的增删查改,将具体问题,转化为计算机级别的建模,先描述,再组织

那么到底什么是进程呢?

用程序来举例子,一个可执行程序的本质是二进制文件,保存在磁盘中,在运行时要将程序先加载到内存中;计算机上的软件,如微信,qq,本质上也是一个.exe的可执行程序,在启动时都要先加载到内存中。

这些可执行程序,在被加载到内存中后,就会变成一个个进程!

加载到内存后,如何对这些进程进行管理呢?

对每一个进程,都由一个 内核PCB 和 可执行程序 组成,这个内核PCB也被称为进程控制块(process ctrl block)。

这个内核PCB可以看做一个结构体,这个结构体中包含进程的状态、优先级、标识符、内存指针等包含进程信息的所有属性字段。对进程的管理,可以看做对每一个进程PCB的管理,所有对进程的控制和操作,都只与进程的PCB有关,与进程的可执行程序无关!

总结:对进程的管理,可以粗略的看做在多个PCB对象形成的链表中,对一个个结点进行增删查改

几乎所有的指令,都是程序,加载到内存运行起来后也要变成进程。CPU的主要工作就是在内存中取指令 -> 分析指令 -> 执行指令 这个周期内进行循环。

CPU中也存在着一个 存储器PC ,PC里的指令指针 IP/EIP等存储正在执行指令的下一条指令的地址,指令指针指向哪一个进程的代码,就表示哪一个进程即将调度!判断、循环、函数跳转指令的本质,就是修改储存器PC里的指令指针指向。

进程状态

创建一个进程的,系统中就多了一个进程!在Linux中普通进程都有它的父进程,每个进程都会有一个编号叫 pid ,每次启动进程的 pid 几乎都会变化,因为这个进程是全新的进程!

下面代通过 父进程创建子进程的过程 来测试新创建的进程

fork()函数,头文件 #include<unistd.h>

fork()函数用来创建子进程,有两个返回值,给子进程返回0,给父进程返回子进程的id。(在Linux中,可以用同一个变量名,表示不同的内存) 

 #include<stdio.h>                                                                                                           #include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/wait.h>int main(){pid_t id = fork();if(id == 0){printf("我是子进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);exit(0);}else{printf("我是父进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);}}  

子进程被创建,其实是以父进程为模板的:子进程会将父进程的字段信息浅拷贝过来,利用写时拷贝(写的时候再进行开空间深拷贝,否则就浅拷贝)来优化创建进程的效率。 

运行结果: 

一个进程崩溃了,是否会影响其他进程的运行? 

仅从运行上来说是不会的,任意进程之间具有独立性,互相不影响。

测试:父进程崩溃了,是否会影响子进程的运行?

  #include<stdio.h>                                                                                                                   #include<unistd.h>#include<stdlib.h>#include<sys/types.h>#include<sys/wait.h>int main(){pid_t id = fork();while(1){if(id==0){printf("我是子进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);sleep(1);}else{printf("我是父进程,my_pid:%d,my_ppid:%d,return id:%d\n",getpid(),getppid(),id);sleep(1);}}return 0;}

使用 kill -9 指令杀死父进程 

可以看到杀死父进程后,子进程依然还在运行,但它的 ppid 发生了改变,变成了‘孤儿进程’。

进程排队

就算进程放在了CPU上,进程也不会是一直在运行的!

CPU中有时间片的概念,即CPU会给当前进程分配一个时间片的时间(极短)来运行,后面的进程按开启时间顺序进行排队,一旦时间片上的时间耗尽,当前进程依然没有运行结束,CPU就会进行切换进程,未完成的进程继续入队,等待下一次调度。这种方式公平、高效,可以有效防止进程阻塞或者挂起而造成CPU资源的浪费!

宏观上来看,我们可以同时打开多个软件,仿佛有很多程序在同时运行。但是实际上,CPU每次只能处理一个进程的内容,只是轮换的时间极短,我们没有发现而已。

进程阻塞

上面提到了进程阻塞的概念,那么进程阻塞一般是什么样的场景呢?

如我们运行一个C语言程序,在程序启动的那一刻,就被加载到内存上,形成了一个进程。这个程序中有需要使用者用键盘输入的部分,但使用者迟迟没有输入。在等待的这段过程中,这个进程看似在运行中,但CPU不可能一直等待着使用者输入。这时候进程就会将自己设置为阻塞状态,根据不同的阻塞类型排入不同的等待队列进行排队,等待软件或硬件资源就绪后再继续运行。

所以总结下来:当进程在等待软硬件资源的时候,且资源没有就绪,进程就会将自己设置为阻塞状态,处于阻塞状态的进程会根据等待资源的不同而被连入多个等待队列中!

进程挂起

当计算机资源吃紧的时候,操作系会对一些优先级不高的进程设置为挂起状态,并将其移到外存,等到条件允许了再将这个进程调回内存中。

僵尸进程

每一个进程的创建都是为了完成某些用户需要的工作的,所以这些进程必须有结果、有数据(进程状态)。进程退出后,它的这些进程状态还需要它自己维持住,供上层读取。

当某个进程死亡(退出)后,它的进程状态没有被他的父进程读取,那这个进程目前的状态,就是僵尸状态。僵尸状态的进程,会一直存在,内存得不到释放,会造成内存泄漏!

孤儿进程

一个进程的父进程先于子进程死亡(退出),那这个子进程就会被1号进程过领养,变成一个孤儿进程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLM之Prompt(三)| XoT:使用强化学习和蒙特卡罗树搜索将外部知识注入Prompt中,性能超过CoT,ToT和GoT

​论文地址&#xff1a;https://arxiv.org/pdf/2311.04254.pdf 一、当前Prompt技术的局限性 LLM使用自然语言Prompt可以将复杂的问题分解为更易于管理的“thought”可以回复用户的问题。然而&#xff0c;大多数现有的Prompt技术都有局限性&#xff1a; 输入输出&#xff08;I…

【QT 5 调试软件+Linux下调用脚本shell-经验总结+初步调试+基础样例】

【QT 5 调试软件Linux下调用脚本shell-经验总结初步调试基础样例】 1、前言2、实验环境3、自我总结4、实验过程&#xff08;1&#xff09;准备工作-脚本1&#xff09;、准备工作-编写运行脚本文件2&#xff09;、给权限3&#xff09;、运行脚本 &#xff08;2&#xff09;进入q…

pytorch一致数据增强

分割任务对 image 做&#xff08;某些&#xff09;transform 时&#xff0c;要对 label&#xff08;segmentation mask&#xff09;也做对应的 transform&#xff0c;如 Resize、RandomRotation 等。如果对 image、label 分别用 transform 处理一遍&#xff0c;则涉及随机操作的…

计算机网络网络层(期末、考研)

计算机网络总复习链接&#x1f517; 目录 路由算法静态路由与动态路由距离-向量算法链路状态路由算法层次路由 IPv4&#xff08;这个必考&#xff09;IPv4分组IPv4地址与NAT子网划分与子网掩码、CIDRARP、DHCP与ICMP地址解析协议ARP动态主机配置协议DHCP IPv6IPv6特点 路由协议…

android studio 创建按钮项目

1&#xff09;、新建一个empty activity项目&#xff0c;切换到project视图&#xff1a; 2&#xff09;、修改app\src\main\res\layout\activity_main.xml文件&#xff0c;修改后如下&#xff1a; <?xml version"1.0" encoding"utf-8"?> <andr…

设置Ubuntu或树莓派系统,允许root用户ssh方式连接

Ubuntu 或 Raspbian 系统默认不允许root 用户以ssh方式连接。连接会报如下错误&#xff1a; Permission denied&#xff0c; please try again. 解决步骤&#xff1a; &#xff08;如果是树莓派系统&#xff1a;烧录到内存卡后&#xff0c;拔掉内存卡再重新插到PC机上&#x…

html基础知识

1、文字阴影代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <meta http-eq…

Vue 工作开发小技巧

一、汇总 ​ 本博客&#xff0c;记录了一些Vue在日常开发工作中比较实用的小技巧&#xff0c;后续会陆续添加更新。 ​ 1、利用Sass的:global定义全局样式。 ​ 2、在<style>内部使用v-bind给CSS属性绑定属性值。 ​ 3、父子组件传值时&#xff0c;使用.sync修饰符后…

#HarmonyOS:访问应用资源--系统资源

访问应用资源 在工程中&#xff0c;通过"$r(‘app.type.name’)"的形式引用应用资源。app代表是应用内resources目录中定义的资源&#xff1b;type代表资源类型&#xff08;或资源的存放位置&#xff09;&#xff0c;可以取“color”、“float”、“string”、“plu…

cgteamwork与shotgrid对比

最近有项目接触使用并二开cgteamwork&#xff0c; 也重新认识了cgteamwork&#xff0c;感受到国产软件的强大&#xff0c;国内中小CG公司的首选&#xff0c;原因&#xff1a; 1 上手容易&#xff0c;不会的有售前工程师教&#xff0c;他们全国各地城市到处跑。 感概业务的强大…

Linux: 查看服务器的CPU信息

在linux服务器环境下&#xff0c;可以使用cat /proc/cpuinfo命令查看当前CPU的核数等信息。 cat /proc/cpuinfo 字段解析 /proc/cpuinfo 是一个特殊的文件&#xff0c;在 Linux 系统中提供有关 CPU 的详细信息。它实际上是一个伪文件系统中的文件&#xff0c;通过它可以获取到…

智能优化算法应用:基于生物地理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于生物地理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于生物地理学算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.生物地理学算法4.实验参数设定5.算法…

Visual studio+Qt开发环境搭建以及注意事项和打开qt的.pro项目

下载qt-然后安装5.14.2_msvc2017 不知道安装那个就全选5.14.2的父级按钮 https://download.qt.io/archive/qt/5.14/5.14.2/ 安装Visual studio,下载直接下一步就行 配置Visual studio的qt环境 在线安装-重启Visual studio会自动安装 离线安装-关闭Visual studio点击安装 关闭…

c++向线程函数传递参数及编译错误排查

c向线程函数传递参数及编译错误排查 普通传递 void func(int a) {cout << "a " << a << endl; }int main() {thread t(func, 1); // 第一个是函数名字&#xff0c;第二个函数的参数t.join(); // 注意&#xff0c;不写join会报core dumped }当传…

find_package 和 find_library的区别

背景 经常看CMakeLists.txt中有find_package和find_library&#xff0c;有时候没留意以为都一样&#xff0c;其实二者差距比较大&#xff0c;下面简单记录一下。 find_package find_package(NAME), 这段代码的本质就是在找一个NAME.cmake这个文件&#xff0c;一般在安装库的…

在Java中,为什么在lambda表达式中访问局部变量时,必须将其声明为final或等效的原因是?

lambda表达式实际上是对该变量的一个拷贝而不是引用。 这样做有几个原因&#xff1a; 线程安全性&#xff1a;当一个lambda表达式被创建并传递给另一个线程时&#xff0c;它可能在另一个线程上执行。如果在lambda表达式中访问非final的局部变量&#xff0c;并且该变量在执行过…

桂电|《操作系统》实验一:UNIX/LINUX及其使用环境(实验报告)

桂林电子科技大学2023-2024学年 第 一 学期 操作系统A 实验报告 实验名称 实验一 UNIX/LINUX及其使用环境 实验指导老师&#xff1a; 成绩 院 系 计算机与信息安全学院 专业 计算机科学与技术(卓越工程) 学 号 姓名 课内序…

Docker助力前端开发,轻松打造高效应用

https://docs.docker.com/engine/reference/builder/ 构建前端镜像 在开发和部署前端应用程序时&#xff0c;使用Docker可以提供一个简便而可靠的方式来打包、分发和运行应用程序。 1. 创建Dockerfile 首先&#xff0c;我们需要创建一个Dockerfile&#xff0c;该文件用于定义…

Spring Boot+FreeMarker=打造高效Web应用

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于Spring BootFreeMarker的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一. FreeMarker是什么 二…

【点云异常点检测】MVTec AD数据集介绍

文章目录 一、简介二、每种类型模型个数 一、简介 MVTec AD&#xff08;MVTec Anomaly Detection&#xff09;数据集是用于异常检测的计算机视觉数据集。该数据集包含来自工业生产中不同材料和产品的图像&#xff0c;包括玻璃、塑料、纺织品等。每个类别都包含正常样本和异常样…