Linux:进程概念

1.冯诺依曼体系结构

结论:
--- CPU不和外设直接打交道,和内存直接打交道。
--- 所有的外设,有数据需要收入,只能载入到内存中;内存写出,也一定是写道外设中。
--- 为什么程序要运行必须加载到内存?
     写好的程序存储到磁盘上,cpu要执行代码访问数据,只能从内存中读取(体系结构规定)。
--- 进度条代码:为什么已经调用了printf函数,但是数据没有被打印出来?
     显示器是外设,你的代码加载到内存cpu跑,跑完之后不是直接写入到外设的,而是写给内存,交给它一段时间后刷新,才被写入到外设输出出来。
--- 计算机怎么知道输入设备中有数据呢?
     各种外设和cpu在控制之间存在交互。
--- cpu中的控制器是用来响应外设的一些请求,它去告诉cpu;还有一些芯片专门用来把外设数据搬到内存,数据就绪状态的捕捉;cpu中的运算器进行算术运算和逻辑运算。

2.操作系统

操作系统是一个进行软硬件资源管理的软件,为用户提供稳定的、高效的、安全的执行环境。操作系统内包括进程管理、文件系统、内存管理、驱动管理。 管理者对重大事情做决策,但不需要和被管理者直接交互。决策需要有依据,依据的来源是数据! 
计算机如何管理硬件?
用struct结构体描述硬件各属性,然后用链表或其它数据结构将各硬件组织起来。

3.什么是进程?

一个运行起来(加载到内存)的程序---进程。 同一时期有很多磁盘上的程序要加载到内存上。操作系统要对这些进程进行管理,引入PCB的概念进行对进程的描述---进程控制块struct task_struct{进程属性},进程ID、属性、状态、优先级、数据......。当程序加载到内存里,系统给每一个进程匹配一个进程控制块,操作系统遍历链表(存储单元为进程控制块),将死亡状态的进程清除,将优先级高的进程加载到CPU---对进程的管理转化成了对链表的增删查 。管理的理念---先描述再组织。

---进程演示,进程在调度运行的时候,具有动态属性!

---在Linux下,当程序加载在内存中,然后将myproc二进制文件删除掉,进程不会关闭!一个进程在运行时一定加载的是磁盘上的某个程序,如何知道进程加载的是哪个磁盘上的程序,系统上标识
---getpid()获取子进程、getppid()获取父进程,重启进程每次子进程id每次发生变化,但是父进程id每次都不变。我们在登陆时,操作系统给指派了一个shell,命令行上启动的进程一般它的父进程没有特殊情况的话都是bash!./myproc这个任务交给子进程去跑,哪个子进程出问题了不会影响到父进程,但是如果父进程出问题了命令行解释器就会崩掉。 
---fork()创建子进程;fork是一个函数,在它执行前:父进程,执行后:父进程+子进程,fork()之后的代码,fork()函数的返回值;pid_t,同一个变量id,会给父进程返回子进程的id,给子进程返回0。被父进程和子进程共享!可以根据返回id不同让父子进程执行后续不同部分的代码。

4.进程状态:

1.运行状态:一般一个cpu会维护一个进程的运行队列,进程入队列---让进程的PCB结构体去排队。队列的存储数据类型是task_struct,在运行队列的所有进程都叫做运行状态(包括正在运行/在运行队列)。cpu运行处理某一个进程时,根据pcb去内存中查找储存着对应的code/data块去调用运行。进程的状态就是它的一个属性,在task_struct中存储。
2.阻塞状态:进程不只是只占用CPU资源,当cpu正在执行某个进程时,发现它需要调用某个外设资源时,由于外设速度很慢,就会先将它放到某外设队列去排队,这个状态就叫阻塞状态。当在外设处理完毕后,操作系统将它的状态改为R,重新放到运行状态中。所谓的进程不同的状态,本质上是进程在不同的队列中等待某种资源。
3.挂起状态:由于内存的空间有一定的限制,阻塞状态的任务又需要等待很长时间,d操作系统就会先将该任务的code/data换出保存在磁盘的某个区域,保留它的task_struct。阻塞状态不一定会挂起(内存不够才会挂起),只要不是运行状态都有可能被挂起。当阻塞状态结束,操作系统将该进程资源重新加载到内存,运行状态改为R,放入cpu的运行队列。
4.内存数据的换入换出:将进程的相关数据,从磁盘加载到内存、从内存保存到磁盘某个区域。

5.Linux下的进程

在实际的操作系统中,阻塞状态、挂起状态这些不会暴露给用户,只会提供用户有用的信息。
---前台进程:状态后面带+,一直在会在显示器打印,不能再键入shell命令,用ctrlC可以终止。
---后台进程:不带+,一直在显示器打印但是可以键入别的命令也会夹杂打印,用ctrlC不能终止,只能用kill -9 pid杀死该进程。
1.查看进程运行状态R:运行状态时间很短,经常会进入S状态排队。
2.查看进程休眠状态S:当程序调用需要访问外设时,就会进入休眠状态,阻塞状态的一种。
3.查看进程深度睡眠状态D:
4.查看进程暂停状态T:一个正在运行的程序,kill -19 pid暂停状态变为T ,kill -18 pid继续运行。
5.查看进程追踪暂停状态t:当代码文件进入gdb调试时,调试的过程等待输入指令时就是追踪暂停状态。
6.查看进程将亡状态Z:fork用父进程创建子进程,退出子进程,继续运行父进程,此时子进程并没有被回收,就是僵尸状态。进程结束会释放data/code,但是还没有释放PCB,等待回收后才能回收PCB,不回收会造成内存泄漏。
7.孤儿进程:父进程如果提前退出,子进程就会被操作系统“领养”,它的PPID变为1(操作系统进程)。例:fork用父进程创建子进程,然后杀死父进程,子进程的PPID就会变成1。

6.进程优先级(简单了解)

1.什么叫做优先级?
先/后获得某种资源的权利。
2.为什么会存在优先级?
资源有限,要访问资源的进程很多。
3.Linux优先级特点---很快
---PRI:老的优先级,不会被改也不能被改。
---NI:取值范围【-20,19】。通过top修改,sudo top ,PID,新Nice值,uit退出。
在Linux当中,一个进程的 最终优先级=老的优先级 + nice;Linux支持进程运行中,通过修改nice值修改优先级,大部分情况下nice默认为0。我们可以把一个进程运行起来后调整他的优先级。

7.进程的相关特性

进程之间具有竞争性、独立性--运行期间互不干扰。
任何时刻,只有一个进程正在运行;多个进程在多个CPU下并行运行
Windows下:一个cpu好似多个进程都在跑,时间片轮转:不管进程执行完花多长时间,每次给定一段时间让它占领cpu,时间到了继续返回运行队列排队,采用轮转的方式使得多个进程可以同时推进,这种方式叫做并发。通过进程切换的方式可以在一个时间段内让多个进程“同时运行”。

进程切换:

cpu有一套寄存器:取指令、分析指令、执行指令。指令--代码中
例:pc/eip寄存器:永远保存当前正在执行指令的下一条指令的位置。
当我们的进程在运行时,一定会产生很多的临时数据,比如加法运算的中间结果。这份数据属于当前进程。cpu内部虽然有一套寄存器硬件。但是,寄存器里面保存的数据,是属于当前进程的。
进程在运行时占有cpu,但不是占用到进程结束。进程在运行时都有自己的时间片。
上下文保护和上下文恢复:暂且认为将A进程运行中产生的临时数据暂时保存在PCB中,剥离当前的进程,轮转下一个进程。等到A进程继续轮转时,首先恢复它数据,加载到寄存器中。

8.环境变量

环境变量是操作系统为了满足不同的应用场景而预先在系统中设置的一大堆全局变量,这些变量在整个系统中一直都会被其它进程访问到。
command not found
要执行一个指令或程序,先找到这个程序。 ./myprocess -》 ./表示当前路径
将我们的程序拷贝到系统安装指令下,就可以不加./直接运行了。sudo cp myprocess  /usr/bin/
没经过测试的程序最好不要安装在bin下,sudo rm myprocess  /usr/bin/
添加到环境变量中:echo $PATH输出系统的环境变量,pwd查询当前路径,将当前路径添加到环境变量中,export PATH=$PATH:/ / /。$PATH将老的环境变量先加载进来再添加新的,直接添加自己的环境变量的话会导致整个PATH文件被覆盖。
当自己的可执行程序的路径也被添加到环境变量中后,也可以用which查询
cd ~,vim /etc/bashprofile -> vim /etc/bashrc配置文件中环境变量的设置,在系统启动后加载到内存
---env‌是一个外部命令,用于列出当前系统的所有环境变量及其赋值。
---PATH‌是一个环境变量,用于指定操作系统在命令行中搜索可执行文件的目录列表。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define USER "USER"
#define MY_ENV "myval"
int mai()
{char *who = getenv(USER);if(strcmp(who,"root")==0)
{printf("user:%s\n",who);printf("user:%s\n",who);printf("user:%s\n",who);
}else printf("权限不足!\n");return 0;
}
int main()
{char *myenv = getenv(MY_ENV);if(NULL==myenv){printf("%s,not found\n",MY_ENV);return 1;}printf("%s-%s\n",MY_ENV,myenv);return 0;

USER环境变量最大的意义,可以标识当前使用Linux的用户
bash就是一个系统进程,mycmd也会变为一个进程(会由fork创建),是bash的子进程,由于环境变量的全局属性,子进程也能访问环境变量;但对于自己创建的myval,只在当前bash下创建,由当前bash产生的子进程都不能访问它。本地变量也可以用set添加: ls显示的是该目录下的文件,shell在当前目录变化时会改变配置文件PWD

9.命令行参数

main()函数可以带参数吗?可以带几个参数?可以带什么参数? 
int main(int argc, char *argv[ ] ) ;

int min(int argc,char* argv[])
{for(int i=0;i<argc;i++){printf("argv[%d]->%s\n",i,argv[i]);}return 0;
}


在我的进程的上下文中,获取环境变量的三种方式:
1.getenv,更加推荐。拿到的是等号后面的内容,其它两种是整行输出。

int main()
{char* myusr = getenv(USER);printf("%s\n",myusr);return 0;
}

 2.char *env[ ]

int main(int argc,char* argv[],char* env[])
{for(int i=0;env[i];i++){printf("%s\n",env[i]);}return 0;
}

3.extern char **environ,指向env的那张表,存储的系统中的环境变量

int main()
{extern char **environ;for(int i=0;environ[i];i++)//这里为什么降维了?{printf("%s\n",environ[i]);}return 0;
}


补充:putenv(),改变或者添加一个环境变量
stat 获取文件的所有属性

10.程序地址空间

多进程在读取同一个地址时,读出来的值不同!-> 这里的指针指向的地址,不是物理地址,是虚拟地址。

#include<stdio.h>
#include<unistd.h>
int global = 100;
int main()
{pid_t id = fork();if(id<0){printf("error!\n");return 1;}else if(id==0){int cnt = 0;while(1){printf("我是子进程! pid:%d,ppid:%d,global:%d,&global:%p\n",getpid(),getppid(),global,&global);sleep(1);cnt++;if(cnt==10){global = 300;printf("子进程已经更改了global!\n");}}}1,17          else{while(1){printf("我是父进程! pid:%d,ppid:%d,global:%d,&global:%p\n",getpid(),getppid(),global,&global);sleep(2);}}return 0;
}

在global被改变后,子进程打印300,父进程打印100?---发生了写时拷贝

地址空间的本质:是内核的一种数据结构 mm_struct  //以32位为例
---地址空间描述的基本空间大小是字节
---32位下能够表示 2^32次方个地址->只要保证唯一性即可
---2^32*1字节 = 4GB空间范围
---每一个字节都要有唯一的地址,给每一个字节用32bit位的地址表示

为什么 存在地址空间
---1.如果让进程之间直接访问物理内存,万一进程越界非法操作呢?
      非常不安全。页表拦截非法操作!
---2.地址空间的存在可以更方便的进行进程和进程数据代码的解耦,维持进程独立性这样的特征。
写时拷贝:任何一个进程尝试写入时,操作系统先进行数据拷贝,更改页表映射,然后再让进程进行修改。操作系统,为了保证进程的独立性,做了很多工作! ---通过地址空间和页表,让不同的进程,映射到不同的物理内存处。
---3.再一次理解地址空间
在磁盘中的可执行程序里面,有没有地址呢?(还没有加载到内存的时候),这个地址是什么地址?
---调C库函数的时候需要链接,链接的过程就是将库中需要用到的函数的地址加载到程序中形成可执行程序,这个地址叫做逻辑地址。
---虚拟地址空间,不是只有操作系统会遵守对应的规则,编译器也要遵守!编译器在编译代码时,会按照虚拟地址空间规则划分代码区/数据区(堆和栈运行时才会产生),编译器按照虚拟地址空间的方式同时对我们的代码和数据进行编址。当程序被加载到物理内存中的时候,该程序对应的指令和数据,都天然的具有了物理地址!

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

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

相关文章

活动预告 | Microsoft Azure 在线技术公开课:使用 Azure OpenAI 服务构建生成式应用

课程介绍 通过 Microsoft Learn 免费参加 Microsoft Azure 在线技术公开课&#xff0c;掌握创造新机遇所需的技能&#xff0c;加快对 Microsoft Cloud 技术的了解。参加我们举办的“使用 Azure OpenAI 服务构建生成式应用”活动&#xff0c;了解如何使用包括 GPT 在内的强大的…

Flutter:打包apk,详细图文介绍

困扰了一天&#xff0c;终于能正常打包apk安装了&#xff0c;记录下打包的流程。建议参考我这篇文章时&#xff0c;同时看下官网的构建说明。 官网构建并发布 Android 应用详情 1、AS创建Flutter项目 2、cmd执行命令 生成一个sunluyi.jks的文件&#xff0c;可以自行把sunluyi替…

【服务器学习专栏 1.2 -- 带外管理】

请阅读 嵌入式学习必备专栏 文章目录 Overview服务器带外管理BMC 介绍BMC 特点BMC 工作原理 Overview 从技术的角度&#xff0c;网络管理可分为带外管理&#xff08;out-of-band&#xff09;和带内管理&#xff08;in-band&#xff09;两种管理模式。 带内管理&#xff0c;是指…

南京市建邺区南苑街道一行莅临园区考察交流

2024年8月28日&#xff0c;南京市建邺区南苑街道办事处副主任董兵、南苑街道发展服务办公室一级主任科员王洪政、建邺区国资集团科创公司经理杲畅&#xff0c;在树莓集团华东区负责人田林和陈强经理的陪同下&#xff0c;莅临集团总部-国际数字影像产业园考察交流。 树莓科技&am…

docker中使用nginx

宿主机和docker中nginx做映射 宿主机中nginx 映射目录 /root/myDockerData/devnginx 在容器中相关位置分别是&#xff1a; 配置文件位置&#xff1a;/etc/nginx/ 日志位置&#xff1a;/var/log/nginx/ 项目位置&#xff1a;/usr/share/nginx/html 如下配置启动命令行&#x…

Casino Royale靶场wp

0x00 下载安装 https://download.vulnhub.com/casinoroyale/CasinoRoyale.ova 导入vmware启动 0x01 主机信息收集 0x02目录扫描 index.php 获取到一个域名 修改本地hosts 添加一行 路径&#xff1a;C:\Windows\System32\drivers\etc 192.168.2.20 casino-royale.local 点击…

智能家居体验大变革 博联 AI 方案让智能不再繁琐

1. 全球AI技术发展背景及智能家居市场趋势 人工智能&#xff08;AI&#xff09;技术的飞速发展正在推动全球各行业的数字化转型。国际电信联盟与德勤联合发布《人工智能向善影响》报告指出&#xff0c;全球94%的商界领袖认为&#xff0c;人工智能技术对于其企业在未来5年内的发…

鸿蒙开发(27)案例今日任务

案例为纯前端实现&#xff0c;总结案例。 主页面代码 import { TaskStatisties } from ../view/TaskStatisties import { TaskItem } from ../view/TaskItem import CreateTaskModel, {TaskModel} from ../viewmodel/TaskModel import { router } from kit.ArkUI// xxx.ets En…

WPF编程excel表格操作

WPF编程excel表格操作 摘要NPOI安装封装代码测试代码 摘要 Excel操作几种方式 使用开源库NPOI(常用&#xff0c;操作丰富)使用Microsoft.Office.Interop.Excel COM组件(兼容性问题)使用OpenXml(效率高)使用OleDb(过时) NPOI安装 封装代码 using System; using System.IO; u…

音视频采集推流时间戳记录方案

音视频同步更多文章 深入理解音视频pts&#xff0c;dts&#xff0c;time_base以及时间数学公式_视频pts计算-CSDN博客 ffplay音视频同步分析_ffplay 音视频同步-CSDN博客 音视频采集打时间戳设计 实时音视频数据的采集和处理场景。具体来说: 采集阶段: 在音视频数据采集过…

专业140+总分410+南京大学851信号与系统考研经验南大电子信息通信集成电路,真题,大纲。参考书。

本人本科中等211&#xff0c;离保送本校差一点&#xff0c;考研前纠结本校还是追求更高目标&#xff0c;和家人聊了自己的想法&#xff0c;感谢父母对我的支持&#xff0c;坚定报考南大的目标&#xff0c;最终专业851信号与系统140&#xff0c;总分410顺利被南京大学录取&#…

【C++】初识C++之C语言加入光荣的进化(上)

写在前面 本篇笔记作为C的开篇笔记&#xff0c;主要是讲解C关键字(C98)连带一点点(C11)的知识。掌握的C新语法新特性&#xff0c;当然C是兼容C的&#xff0c;我们学习C的那套在C中也是受用。 ps:点我跳转下集 文章目录 写在前面一、命名空间域1.1、命名空间域的定义与使用1.2…

CGAL windows 安装教程

1.下载源代码 CGAL官网下载https://github.com/CGAL/cgal/releases 2.下载boost库 BOOST官网下载https://www.boost.org/ 3.下载 GMP and MPFR 4.配置VS2022 头文件&#xff1a; 库路径 做完以上步骤&#xff0c;可以使用CGAL了&#xff01;

从0入门自主空中机器人-2-2【无人机硬件选型-PX4篇】

1. 常用资料以及官方网站 无人机飞控PX4用户使用手册&#xff08;无人机基本设置、地面站使用教程、软硬件搭建等&#xff09;&#xff1a;https://docs.px4.io/main/en/ PX4固件开源地址&#xff1a;https://github.com/PX4/PX4-Autopilot 飞控硬件、数传模块、GPS、分电板等…

GraphRAG 框架哪家强?选择最适合你智能问答系统的框架

GraphRAG 框架哪家强&#xff1f;选择最适合你智能问答系统的框架 点击进入&#xff1a;GraphRAG系列文章-Nano-GraphRAG&#xff1a;打造轻量级医疗诊断助手 点击进入&#xff1a;GraphRAG系列文章-突破传统知识管理瓶颈&#xff1a;LlamaIndex GraphRAG 让企业知识问答更智能…

Mac电脑python多版本环境安装与切换

我当前是python3.9.6环境&#xff0c;需要使用3.9.8环境&#xff0c;通过brew安装3.9.8版本&#xff0c;然后通过pyenv切换环境 步骤 1: 安装 pyenv brew install pyenv brew install pyenv-virtualenv 步骤 2: 安装 Python 3.9.8&#xff08;使用 pyenv 安装指定版本的 Pyth…

Redis--持久化策略(AOF与RDB)

持久化策略&#xff08;AOF与RDB&#xff09; 持久化Redis如何实现数据不丢失&#xff1f;RDB 快照是如何实现的呢&#xff1f;执行时机RDB原理执行快照时&#xff0c;数据能被修改吗&#xff1f; AOF持久化是怎么实现的&#xff1f;AOF原理三种写回策略AOF重写机制 RDB和AOF合…

C高级:思维导图Day2

目录 总览1 总览2 总览1 压缩与解压缩 打包与解包 软连接与硬链接 ubuntu下关机与重启指令 总览2 结束

权限获得第一步

权限获得第一步 下载打开附件 给了一串加密的密文 一般都是用MD5加密&#xff0c;每一段分别解码一下 第一段不行&#xff0c;试一下第二段 这里发现第二段可以解码出来&#xff0c;这应该就是密码了 flag{3617656}

001__VMware软件和ubuntu系统安装(镜像)

[ 基本难度系数 ]:★☆☆☆☆ 一、Vmware软件和Ubuntu系统说明&#xff1a; a、Vmware软件的说明&#xff1a; 官网&#xff1a; 历史版本&#xff1a; 如何下载&#xff1f; b、Ubuntu系统的说明&#xff1a; 4、linux系统的其他版本&#xff1a;红旗(redhat)、dibian、cent…