当前位置: 首页 > news >正文

Linux(7)——进程(概念篇)

一、基本概念

书本上的概念:程序的一个执行实例,正在执行的程序等

基于内核的观点:担当分配系统资源(CPU时间,内存)的实体。 

我们知道,我们在写代码的时候,你的代码进行编译链接后生成可执行文件,这个文件就在磁盘当中,当我们双击这个文件之后,该文件就被加载到了内存之中,因为只有加载到了内存之中才能被cpu逐语句执行。而加载了内存中的程序,不再是程序而应该是进程。 

 

二、描述进程——PCB

实际上我们在系统当中有很多的进程,我们可以通过ps aux命令来查看:

我们知道操作系统是第一个被加载到内存的,而操作系统就是做的管理工作的,那么操作系统是怎么做到管理的呢?

这里就用到了之前在谈操作系统时候提到的六个字:先描述,再组织。操作系统作为管理者,是不需要与进程直接交互的,当进程到来时,操作系统需要对进程进行描述,那么对进程的管理就变成了对描述的管理。进程的描述信息会被放到一个叫进程描述块之中,官方称之为PCB(process control block)。

操作系统将每一个进程都进行描述,形成了一个个的进程控制块(PCB),并将这些PCB以双链表的形式组织起来:

这样一来,操作系统只要拿到这个双链表的头指针,便可以访问到所有的PCB。此后,操作系统对各个进程的管理就变成了对这条双链表的一系列操作。
例如创建一个进程实际上就是先将该进程的代码和数据加载到内存,紧接着操作系统对该进程进行描述形成对应的PCB,并将这个PCB插到该双链表当中。而退出一个进程实际上就是先将该进程的PCB从该双链表当中删除,然后操作系统再将内存当中属于该进程的代码和数据进行释放或是置为无效。
总的来说,操作系统对进程的管理实际上就变成了对该双链表的增、删、查、改等操作。 

1.task_struct——PCB的一种

因为Linux是拿C语言写的,那么这里的task_struct其实是一个结构体。

1)在Linux中描述进程的结构体叫做task_struct。
2)task_struct是Linux内核的一种数据结构,它会被装载到RAM(内存)里并且包含着进程的信息。

2.task_struct的内容分类

主要内容:

  • 标示符:描述本进程的唯一标示符,用来区别其他进程
  • 状态: 任务状态,退出代码,退出信号等。
  • 优先级:相对于其他进程的优先级。
  • 程序计数器:程序中即将被执行的下一条指令的地址。
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据: 进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • 1/0状态信息:包括显示的I/0请求,分配给进程的!/0设备和被进程使用的文件列表。
  • 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。
  • 其他信息

三、查看进程

1.通过系统目录查看

我们除了上面的,通过ps aux命令查看以外,还可以在根目录下找系统文件夹proc。

我们打开文件夹,可以看到一些以数字命名的目录

这些数字就是我们之前所说的PID,在对应的目录中记录了进程的相关信息,比如我们查看1的文件内容:

2.通过ps命令查看

单独使用ps:

ps aux

ps结合grep可以看到更加标准的进程信息:

四、通过系统调用获取进程的PID和PPID 

这里我们要用到两个调用函数,分别是getpid()和getppid()来分别获取PID和PPID。

我们可以写个代码来测试一下:

输出: 

我们也可以看一看进程的信息是不是和我们调用函数获取的一致

五、通过系统调用创建进程

1.fork函数创建子进程

fork函数是一个系统调用函数,他可以创建一个子进程:

例如:

运行结果如下:

运行结果中的第一行数据是该进程的PID和PPID,第二行是、fork函数创建的PID和PPID,不难发现fork函数创建的进程的PPID就是proc的PID,也就是说proc进程和fork创建的进程是父子关系。

没出现一个进程,操作系统都会为其创建PCB,fork也不例外。

我们知道加载到内存的代码和数据是父进程的,那么fork创建的子进程的代码和数据是哪里来的呢?

我们来写个代码来看看:

运行结果:

实际上,fork函数创建子进程,在fork函数之前的代码要被父进程执行,而fork()之后的代码默认是父子进程都可以执行的。

敲黑板:

1)这里虽然是父子进程代码共享,但是父子进程各自开辟空间(写时拷贝)。

2)这里面可能大家都会有一个疑问,那就是这里父子进程的执行顺序是什么样的,其实这里执行的顺序完全是不确定的,取决于操作系统的调度。

2.使用if来引出问题

我们在之前说了,在fork()函数之后的父子进程共享代码,那么这样一来,我们创建子进程就没有了意义,实际上使用的时候是要使用if来分流的,也就是父子进程去做不同的事情。

fork的返回值:

1.如果子进程创建成功了,在父进程中返回子进程的PID,而在子进程中返回0。

2.如果子进程创建失败,则父进程中返回。

既然子进程创建的返回值不一样,那么我们就可以通过这个性质来分流。

代码如下:

运行结果:

六、Linux的进程状态

 

相关文章:

  • 万亿参数背后的算力密码:大模型训练的分布式架构与自动化运维全解析
  • 【RichTextEditor】 【分析2】RichTextEditor设置文字内容背景色
  • 毕业论文格式(Word)
  • python 自动生成不同行高的word
  • 攻防世界——Web题 unseping 反序列化绕过
  • 计算机视觉与深度学习 | 基于 YOLOv8 + BeautyGAN + CodeFormer + Face Parsing 实现简单的人脸美颜
  • Spring Security探索与应用
  • 如何进行CAN一致性测试
  • 从稳定到卓越:服务器部署后的四大核心运维策略
  • 传奇各种怪物一览/图像/爆率/产出/刷新地/刷新时间/刷怪时间
  • LeetCode 2942.查找包含给定字符的单词:使用库函数完成
  • vs2022 Qt Visual Studio Tools插件设置
  • 人工智能100问☞第31问:如何评估一个AI模型的性能?
  • IPC进程间通信详解
  • 索引下探(Index Condition Pushdown,简称ICP)
  • MCP与AI模型的多语言支持:让人工智能更懂世界
  • 数据库6——综合实验-水果商店进阶一
  • Axure酒店管理系统原型
  • Python入门手册:Python中的数据结构类型
  • Gartner《Optimize GenAI Strategy for 4 Key ConsumerMindsets》学习心得
  • 怀化网站优化公司哪家好/网站查找工具
  • 网站访问量统计工具/免费广告推广
  • 北京食药局网站年检怎么做/网络口碑营销
  • 北京建设部网站官网/网站seo属于什么专业
  • 微信网站如何开发/百度在线问答
  • 用adsl做网站备案/seo搜索推广费用多少