进程概念与进程状态_Linux

一.冯・诺依曼体系

输入设备:键盘,网卡这些

CPU=运算器+控制器

存储器:内存

这个体系结构的效率:由设备的"拷贝"效率决定

1.理解数据的流动:

就是两个冯・诺依曼体系的交流

二.操作系统

一个基本的程序集合,称为操作系统(OS)

操作系统是一款进行软硬件管理的软件

操作系统主要包括:

1.内核(进程管理,内存管理,文件管理)

2.其他程序(例如函数库,shell程序等等)

操作系统对上:为用户(应用程序)提供一个良好的执行环境

操作系统对下:与硬件交互,管理所有的软硬件资源(不是目的,是手段)

理解操作系统:

在这个计算机软硬件的架构中,操作系统的定位是:一款"搞管理"的软件

如何理解"管理"?这里打个比方:

校长(管理者)->操作系统

辅导员(执行)->驱动程序

学生(被管理者)->硬件

管理者要管被管理者可以不用见面,是通过"数据"来进行管理,那我们的"数据"就是从我们的执行来获取.校长手中的数据可以是一个Excl表格(链表)(里面有所有学生的基本信息)而且数量大,所以通过辅导员来进行对该表格(数据)的管理

先描述再组织是操作系统资源管理、进程管理、文件管理、设备管理的底层核心设计思想。

三.理解系统调用

操作系统就像一个银行:向上对用户提供对应的服务,但是又不相信任何用户或者人,我们需要设置系统信息都是通过系统调用来实现.

系统调用:各种接口

库函数和系统调用是上下层的关系

四.进程

先描述,再组织.

进程=内核数据对象(PCB)(Process Control Block)+自己的代码和数据!

我们称那些task_struct为进程控制块,进程的所有属性都可以直接或者间接通过task_struct找到

1.task_struct

标识符:描述本进程的唯一标识符,用来区分其他进程.

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

优先级:相对于其他进程的优先级

程序计数器:程序被执行的下一条指令的地址

内存指针:包括程序代码和进程相关数据的指针,还有其他进程共享的内存块的指针(就像你面简历里的电话)

我们历史上执行的所有指令,工具,自己的程序,运行起来,全部都是进程.

2.getpid(process ID)

获取当前进程的 PID

我们man查看手册可以看到getpid的相关信息.pid_t就是一个整数,成功嫉妒pid,失败就是0

找到相应的pid就可以说明她是一个进程

3.ps = process status

可以查到所有进程

复制代码
ps -aux
//查看所有进程

那我们想要查看自己刚启动的进程

cpp 复制代码
ps -axj | grep myprocess
//使用grep过滤信息,找到自己想要的进程

但是上面这个信息乱七八糟的,不知道是什么所以我们需要对应的属性说明

cpp 复制代码
ps -axj | head -1;ps -axj | grep myprocess
//查看第一行的信息
//这里是查到了grep自己的进程

3.kill -9 +PID

就是我们平常使用的ctrl+c

通过kill就可以杀死进程

4.ls /proc/pid

可以查到对应进程的全部信息,在没有杀死进程的前提下.

cwd查看当前进程的绝对路径,每个进程的 PCB 里,都保存着

5.chdir = change directory

改变当前工作目录,会改变cwd所对应的路径

五:研究进程的父子关系

子进程都是父进程创建的

用代码创建子进程:

我们使用man命令去查找fork

子进程没有自己的代码和数据,默认共享父进程的,因为目前没有程序新加载

进程具有独立性

父子任何一方进行修改数据,OS把修改的数据在底层拷贝一份,让目标进程修改这个拷贝(写实拷贝 ),就可以保证独立性

六.进程状态

进程状态就是task_struct内的一个整数

1.运行&&阻塞&&挂起

运行:进程在调度队列中们进程的状态都是running

阻塞:等待某种设备或者资源就绪,就像一个进程需要scanf输入我们就会将它从runqueue放到waitqueue

挂起:操作系统在内存吃紧的时候,在磁盘上的swap交换分区进行换入换出操作,用磁盘扩容虚拟内存,保证系统不崩溃(阻塞挂起),当内存压力极高时,系统会选择暂时挂起部分正在运行的进程,使其转为就绪挂起状态,暂停占用物理内存,缓解内存资源紧张;

2.理解内核链表

我们的双向链表的next指针是直接指向整个节点,但是linux内核是指向节点结构体里面的一个封装的结构体成员对象(里面有next和prev)

怎么访问其他成员对象呢,即外部结构体对象?

使用offset,作用:计算某个成员在结构体中的字节偏移

cpp 复制代码
offsetof(struct my_data, node);

找到外部结构体

cpp 复制代码
#define container_of(ptr, type, member) \
    (type *)((char *)(ptr) - offsetof(type, member))

3.linux的进程状态

cpp 复制代码
// include/linux/sched.h
#define TASK_RUNNING            0       // 运行/就绪
#define TASK_INTERRUPTIBLE      1       // 可中断睡眠
#define TASK_UNINTERRUPTIBLE    2       // 不可中断睡眠
#define __TASK_STOPPED          4       // 暂停
#define __TASK_TRACED           8       // 被追踪(调试)

#define EXIT_ZOMBIE             16      // 僵尸进程
#define EXIT_DEAD               32      // 死亡进程

s是浅度睡眠,是可以被杀死的

d是深度睡眠,是不能被杀死的

僵尸进程:

子进程运行结束后,退出码、运行状态 必须保留,要交给父进程查看。

子进程都是由父进程创建的, 创建子进程的目的是为了子进程完成某种事情.完成的结果的相关信息还需要返回给父进程.进程退出的时候是有相应的信息的,信息存在进程的 PCB(进程控制块)

如果父进程一直不管,不回收,不获取子进程的提出信息,那么Z会一直存在,就会造成内存泄漏

如果进程直接退出了,内存泄漏问题是不存在的,常驻在内存的进程是比较怕内存泄漏的.

子进程代码早就跑完、退出了(没了) 但是父进程还活着,一直不调用 wait 收尸 → 子进程就变成 僵尸进程 Z

孤儿进程:

父子进程关系中,如果父进程先退出,子进程要被1号进程领养,这个被领养的进程(子进程),叫做孤儿进程,被领养只之后就会变成后台进程,ctrl+c就不能杀死了

为什么子进程会被领养?没有被领养就没有父进程

我们子进程没有父进程再子进程结束的时候没有人调用wait()来回收PCB,清理退出状态,系统就会产生大量的僵尸进程,占满PID系统就会卡死.

相关推荐
如君愿1 小时前
考研复习 Day 26 | 习题--计算机网络第三章(数据链路层 下)、数据结构 多维数组与广义表
数据结构·计算机网络·考研·记录考研
znhb991 小时前
九九AI驱动脱硫脱硝及氨逃逸精准控制技术,实现环保、经济、运维三重升级
运维·人工智能
bqq198610261 小时前
MySQL分库分表
数据结构·mysql
wang09071 小时前
Linux性能优化之磁盘基础介绍
linux·运维·性能优化
迷途之人不知返1 小时前
List的模拟实现
数据结构·c++·学习·list
HalvmånEver1 小时前
MySQL的内置函数
linux·数据库·学习·mysql
fleaxin1 小时前
大华海光GPU服务器安装PVE和统信系统虚拟机
服务器·nvidia·pve·uos·统信
marsh02061 小时前
39 openclaw持续集成实践:自动化构建与部署流程
运维·ci/cd·ai·自动化·编程·技术
云边有个稻草人1 小时前
KingbaseES高可用最佳应用实践——全架构部署、故障自愈与运维规范
运维·架构·国产数据库·kes