进程(从操作系统的状态到linux的进程状态一步到位)

进程的概念

我们常见的计算机都遵循冯诺漫体系结构

当我们运行一个可执行程序的时候,开始程序会保存在磁盘上面,运行的时候,会加载到存储器上面,从而cpu进行处理。再返回存储器,再到输出设备。

为什么要先加载到存储器?

因为外设效率太慢,我们cpu不直接和外设打交道,要数据,只能从内存中读取。文件加载到内存上面是按需拷贝,然后cpu是读取地址,然后从内存上读取文件。

CPU 绝不直接等外设,必须让内存做缓冲。

程序运行之前,必须加载到内存。

CPU 不直接读外设,外设直接把数据丢进内存。

当我们在键盘输入泥嚎发送给朋友的时候,键盘小字节的内容直接拷贝加载到内存,

还有拉取文档给朋友,文档本身也在外设磁盘里面,加载 到内存,cpu读取,返回内存,再通过网络一系列发给朋友。

操作系统

什么是操作系统

操作系统是一个对软硬件管理的软件,它也是由c语言写的。

操作系统又分为广义操作系统(window操作系统加图形化界面+软件。linux加指令加shell命令行)

狭义操作系统☞的是操作系统内核。

为什么要有操作系统

操作系统对下进行软硬件管理(手段)。对上给用户提供良好的环境。

没有操作系统,计算机就无法正常的工作。

操作系统是如何管理的

操作系统对软硬件的管理。操作系统不能直接跟软硬件获取数据。要通过驱动程序获取数据,然后进行描述,在组织。

就像校长对于学生,不会当面一个从每个学生获取数据,而是通过辅导员来获取数据的.

先描述是什么?描述就是把被管理者的部分信息用结构体struct管理起来。为什么不用class(因为操作系统是用c语言写的)。

再组织是什么?就是对于每个个体,通过数据结构进行链接。完成对链表的增删查改。

(从而更好的管理,对于进程,我们可执行程序在磁盘硬件上,加载到内存,创建进程。进程就是对程序的描述,如何进行几个进程的组织,如果不执行该程序就会删除)

驱动就是翻译,操作系统和硬件之间的翻译。

什么是系统调用什么 是库函数

在开发⻆度,操作系统对外会表现为⼀个整体,但是会暴露⾃⼰的部分接⼝,供上层开发使⽤,
这部分由操作系统提供的接⼝,叫做系统调⽤。

系统调⽤在使⽤上,功能⽐较基础,对⽤⼾的要求相对也⽐较⾼,所以,有⼼的开发者可以对部
分系统调⽤进⾏适度封装,从⽽形成库,有了库,就很有利于更上层⽤⼾或者开发者进⾏⼆次开

为什么要有系统调用?因为直接让用户访问内核数据结构会存在安全问题。

系统调用也是唯一访问操作系统的接口。

我们使用的printf,等库函数也会封装系统调用,从而高效的访问操作系统。但并不是所有的库函数都有系统调用。

进程

进程的基本概念

进程在书本中被描述为加载到内存的就是进程。但真正的进程,是程序的属性被描述成take_struct,然后用数据结构链接起来。还有映射的代码。进程=内核的数据结构+程序的代码和数据。

进程是如何被管理的

对于程序,软件被操作系统加载到内存中,操作系统会把许多属性描述成为一个结构体放在内存。

它对于的代码(需要的时候才会映射)也会拷贝到内存。对于多个进程,操作系统是如果管理的,就是先描述,再组织。

take_struct内部描述的进程的属性。许多进程会被数据结构链接。所以操作系统对进程的管理变成了对链表的增删查改。

那进程内部的属性包含哪些:

标识符pid:: 描述本进程的唯⼀标⽰符,⽤来区别其他进程。

状态:任务状态,退出代码,退出信号等

优先级:对于cpu在调度的时候,进程相对于其他进程运行的优先级。

程序计时器:程序中即将被执行的下一条指令的地址。

内存指针:与程序代码和进程相关数据的指针。,还有和其他进程共享的内存块的指针
上下⽂数据: 进程执⾏时处理器的寄存器中的数据[休学例⼦,要加图CPU,寄存器]。
I∕O状态信息: 包括显⽰的I/O请求,分配给进程的I∕O设备和被进程使⽤的⽂件列表。
记账信息: 可能包括处理器时间总和,使⽤的时钟数总和,时间限制,记账号等。
其他信息

对内部属性的认识

pid和ppid:表示自己进程的标识符和父进程的标识符。怎么查找了?getpid(),和getppid()

当前进程一般ppid都是bash,注意先执行完前一条命令,再执行后一条命令要用&&,head -1这个是数字1.下面那个是grep code的进程

可以通过这个方式查看当前进程pid和父进程的ppid。

还有函数getpid(),getppid()。

当结束程序的时候,进程也会消失。

进程里面的属性

还有每次重新创建进程的时候,pid都会不一样。

什么是cwd?

进程属性的cwd是什么,其实就是当前进程的路径。为什么要cwd这个属性,当我们在程序读写文件的时候,如果没有这个文件,会在当前路径创建文件。这个cwd就是缺省路径

修改路径:

把路径复制放在cwd的数组里面。char*bf是存放char数组,或者字符串。

创建子进程(frok)

问题一:为什么给子进程返回0,给父进程返回子进程的pid.

因为需要唯一的标识符来识别进程,未来还有一个父进程:多个子进程。

问题二:为什么fork会有两个返回值。

创建子进程,先会拷贝pcb成为子进程,修改部分属性,比如pid,ppid。

问题三:为什么同一个变量n==0,又可以大于0.

对于父进程和子进程他们的数据,子进程是拷贝父进程的pcb,代码是共享的,数据是分开的,这就是进程具有独立性。不仅子进程具有独立性,不同的进程更是独立。

不同一个flag,虚拟地址一样,但是物理内存空间不同,写时拷贝。

进程状态

操作系统的状态示意图。就让我们一一来里了解。

状态就是进程task_struct内部的一个属性。

运行状态

再了解运行状态的时候,我们来了解一个东西。cpu在调用进程的时候,会在调度进程,从cpu获取调度队列。为什么进程会被双链表链接,还有调度队列。我们c语言不是一个结构体只能一种数据结构链接嘛。

知道调度队列的结构体的地址,那我们怎么获取里面的数据了。首先c语言中,我们可以通过 字节最小地址的位置来偏移获取其他地址。对于int知道最小的地址,再偏移3个,然后cpu会根据当前的字节序组合成一个完整的整数类型。

对于我们只知道调度队列结构体的地址怎么知道进程的其他属性了?这就需要我们用一个思维,对于进程开始的地址肯定不是从零开始。那如果我们假设开始从零开始的,再算到成员结构体的偏移度,再从结构体的地址减去偏移度。

结构体的地址(即 &struct_obj)就是结构体第一个成员的最小字节地址。

所以啊,内核这样做更有通用性,一个task_struct就可以属于双链表,又属于调度队列,还有其他数据结构。

我们把在调度队列的进程叫做运行状态。

阻塞状态

就是进程等待某种资源的时候,资源 没有就绪,cpu会让当前进程阻塞住,直到资源就绪。

列如,我们执行输入的程序的时候,键盘没有被摁下,直到键盘被摁下,进程才从阻塞进程调到调度队列。

进程的成员有运行队列,等待队列,所以当进程阻塞的时候,运行队列断开啦,等待队列链接。device里面也有等待队列,但是头节点,用于连接进程中的等待队列。

当遇到scanf的时候,会遇到阻塞,所以会把进程连接到键盘device的等待队列后面。通过进程成员的等待队列的结构体连接。

阻塞挂起和运行挂起

什么是阻塞挂起,就是一个进程被阻塞了,当是内存空间严重不足,进程也没有运行,它的代码和数据占用空间,所以在磁盘开辟一个swap空间。把代码和数据拷贝过去。然后把内存中的删除。

什么是运行挂起,当内存还是不足的时候,一个cpu只能运行一个进程,所以在调度队列的其他进程的代码和数据也可以放在swap区,当需要的时候再换入进来。

对于没有修改的代码可以不放在swap()区,可以直接删除,需要的时候在从磁盘的源文件拷贝。

linux进程状态、

睡眠状态(slepping)

对于一个程序等待某种资源然后继续被cpu调用。等待的过程叫睡眠状态(s)可以被中断,crtl+c;或者kill -9;

暂停状态(T)

暂停状态就是进程不符合要求的工作,os会暂停进程。

在介绍暂停状态的时候,我们先了解什么是前台进程,什么是后台进程。一个终端只能有一个前台组。当然子进程属于父进程的组,所以子父进程都可以是前台进程。前台进程就是状态后面加一个+号。

要从键盘读取为前台进程,所以它的父进程bash就是后台进程了,所以pwd,ls -l等指令就没有用。crtl+c可以结束前台进程。

为什么要有前后台进程?

因为前台进程接受键盘的数据。后台进程不需要数据,也能跑提高效率。

fg加编号可以把后台进程转换为前台进程。

当我们用gdb调试的时候,遇到断点就暂停了,是因为系统让进程处于暂停状态了

不可中断状态(disk sleep)

对于这种状态,当我们大量的io操作的时候,磁盘老,硬件出现故障的时候,就会出现这种状态持续永久。对于平常大量io的时候只会出现短暂的d。对于出现d 状态,如果长时间出现那么会出现坏盘等操作,因为d状态不能杀死。还会进行io操作。

僵死进程

对于僵尸进程是因为一个pcb进程因为进程完成结束或者进程退出。代码和数据会被回收,但是pcb里面的

会等着父进程来读取。如果父进程一直不来读取,进程会处于僵尸状态。进程都会有父进程。

如果进程没有被读取就会出现内存泄漏。因为pcb进程没有被读取。回收.

对于进程结束里面的malloc和new操作进程结束不会出现内存泄漏。但是对于一个软件都会死循环,我们如果没有malloc和free,不管是是前台进程还是后台进程一直malloc都会造成严重的内存泄露。所以我们要free和delete.

为什么linux没有单纯挂起状态?

因为对于可运行状态内存不足被交换到swap区,和等待某种资源,如键盘的输入。这种也会交换到swap区他们都是T状态.

孤儿进程

对于上面子进程退出,父进程没有来读取就会出现僵尸进程。对于孤儿进程则是子进程退出,父进程没有退出。父进程退出了,子进程还在。怎么办?

孤儿进程会pid为1的领养了之后。会变成后台进程。所以只能kill -9加pid来杀死进程。

被领养就是为了pcb里面的信息被读取,pcb不被读取。避免内存泄露。

相关推荐
空中海4 小时前
6.1 主题与暗色模式
运维·服务器·前端·flutter
x-cmd4 小时前
[260412] x-cmd v0.8.13:x free 新增进程内存显示,feishu、telegram REPL 机器人齐上线!
linux·macos·机器人·内存·x-cmd·telegram·feishu
北京智和信通4 小时前
基于IPMI的服务器集中监控与带外管理方案
服务器·服务器监控·ipmi·网管平台·带外监控
昔我往昔4 小时前
Linux修改静态ip
linux·服务器·tcp/ip
c++逐梦人4 小时前
线程同步与互斥
linux·开发语言
ZPC82105 小时前
RViz 虚拟机械臂 / 真实机械臂 / Gazebo 仿真
linux·人工智能·机器人
wanhengidc5 小时前
网站服务器具体功能有哪些?
运维·服务器·网络·网络协议·智能手机
爱学习的小囧5 小时前
嵌套式 ESXi 8.x/9.0 虚拟设备下载与实战指南
java·linux·运维·服务器·虚拟化
hj2862515 小时前
初学linux命令day2
linux·运维·服务器