进程概念与进程状态_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系统就会卡死.

相关推荐
wj3055853783 小时前
课程 9:模型测试记录与 Prompt 策略
linux·人工智能·python·comfyui
abigriver4 小时前
打造 Linux 离线大模型级语音输入法:Whisper.cpp + 3090 显卡加速与 Rime 中英混输终极调优指南
linux·运维·whisper
wangqiaowq4 小时前
windows下nginx的安装
linux·服务器·前端
YYRAN_ZZU4 小时前
Petalinux新建自动脚本启动
linux
charlie1145141915 小时前
嵌入式Linux驱动开发pinctrl篇(1)——从寄存器到子系统:驱动演进之路
linux·运维·驱动开发
Agent手记5 小时前
异常考勤智能预警与处理与流程优化方案 | 基于企业级Agent的超自动化实战教程
运维·人工智能·ai·自动化
于小猿Sup5 小时前
VMware在Ubuntu22.04驱动Livox Mid360s
linux·c++·嵌入式硬件·自动驾驶
cen__y5 小时前
Linux12(Git01)
linux·运维·服务器·c语言·开发语言·git
不仙5207 小时前
VMware Workstation 26.0.0 在 Ubuntu 24.04 (内核 6.17.0) 上的安装与内核模块编译问题
linux·ubuntu·elasticsearch
Mr. zhihao7 小时前
深入解析redis基本数据结构
数据结构·数据库·redis