Linux——进程|描述进程-PCBtask_struct-PCB的一种组织进程 |查看进程父进程和子进程|PID获取|父子关系|fork初识

目录

描述进程-PCB

task_struct-PCB的一种

组织进程 

 查看进程

父进程和子进程 

PID获取 

父子关系 

 fork初识

fork子进程探讨

fork俩个返回值问题 


课本概念:程序的一个执行实例,正在执行的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
进程:对应的代码和数据+PCB结构体

描述进程-PCB

 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block), Linux操作系统下的PCB是: task_struct

cpu不能直接去访问文件中的程序和数据,而是通过访问PCB,才能访问数据和程序

 cpu对进程的管理,变成了对进程PCB结构体链表的增删查改

task_struct-PCB的一种

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

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

组织进程 

管理理念:先描述,再组织 

可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct链表的形式存在内核里。

 查看进程

 我们执行一个程序就是开始一个进程,程序结束,进程结束

 我们改成死循环代码

 查看进程输入ps,ps只能查看自己的终端下的进程,若想查看所有进程输入ps axj

 输入ps axj,此时查看的是系统中所有进程的信息

 还可利用ps axj查看自己的

ps axj | grep 'mypro'

 带上头部 ps axj | head -1 && ps axj |grep 'mypro'

 输入top命令,也可显示系统中的所有进程,相当于任务管理器,退出q

 系统中还有一个proc的目录

 我们可以看到当前进程的PID是21682

 我们在proc 里面可以找到这个数字ls /proc -l

我们可以利用它的pid查看进程,我们所看到的是它进程的所有属性数据

 我们可以看到当前工作目录和可执行程序

cwd是当前进程的工作目录,exe可执行程序

C语言代码->可执行程序->运行可执行程序->每个进程都会有一个属性,来保存自己所在的工作路径(进程运行时所在的工作路径)

进程的当前路径在跟可执行程序在一个路径

也可这样查看属性

 当我们退出程序时,再去查看这个路径,发现已经没有这个路径了

 

 因此/proc里面的文件是动态变化的

父进程和子进程 

PID获取 

 输入man getpid可查看pid

这里面看到的头文件和C语言没有任何关系,这是操作系统提供的头文件

pid_t是操作系统提供的一个pid类型,其实是unsigned int

所有函数在变成进程之后才能被调用

 

 运行

 

 输入kill -9 30254可以终止程序进行,终止进程

 

父子关系 

 man getppid获得父进程ID,get pid获得进程ID

 

 

 这里的父进程ppid是谁?

我们可以看到ppid就是bash,bash是一种shell的一种

无论是系统的命令还是自己编写的程序,都是bash(shell)的子进程

我们关掉bash

 

输什么命令都不起作用 

我们重新登陆即可,但是每次登陆的时候,PPID都不同,每次登陆都是打开bash

 fork初识

 fork:用来创建一个子进程

返回值:1.失败的时候返回-1

                2.成功的时候子进程pid返回给父进程,0返回给子进程

 一个程序没有fork时

 我们加上fork

再次修改

 

 

 

 从fork之后变成了俩个进程,一个是父进程,一个是子进程

  i am parent ....打印的是子进程

 fork之后产生了俩个进程,一个是上面的ret,一个是下面的ret,因为给子进程返回0,给父进程返回子进程的pid,所以上面是父进程,下面是子进程,

子进程的ppid是14672,14672就是父进程的pid

fork子进程探讨

 

 运行之后程序打印了俩次

 执行俩遍是因为创建了子进程,在fork之后代码是父子共享的

 再次修改程序

 运行之后,由于fork成功子进程返回的是0,子进程进入else if,父进程返回的是子进程的PID,父进程进入else,这里的if和else if同时执行,这是因为fork之后有俩个不同的进程流

一个子进程只能有一个父进程,一个父进程可以有多个子进程,所以是父子关系

 输入这个语句可动态观察: while :; do ps axj | head -1 && ps ajx | grep mypro | grep -v grep;sleep 1;done

fork俩个返回值问题 

fork会创建一个子进程,会把0或-1返回给子进程,把子进程PID返回给父进程,为什么会有俩个返回值呢?

 创建子进程的时候,要新建一个task_struct结构体,子进程的内部属性要以父进程为模板,就像父子DNA关系一样

 当准备return时,我们的核心代码已经完成了吗?

 通过task_struct将代码加载到寄存器当中

操作系统和cpu运行某一个进程,本质从task_struct形成的队列中挑选一个task_struct,来执行它的代码,进程调度,变成了在task_struct的队列中选择一个进程的过程

只要想到进程,优先想到对应的task_struct

当我们准备return的时候,核心代码已经完成了,当子进程准备return的时候,子进程已经被创建出来了,甚至放在了运行队列当中

当父进程被cpu调度的时候,会return 一个值给父进程,子进程被调度的时候,会return一个值给子进程,所以会出现return俩次的情况

总结:

1.因为fork内部,父子各自会执行自己的return语句

2.返回俩次,并不意味着会保存俩次

父子进程被创建出来,哪一个先运行?

这个没有固定答案,有可能是父进程,也有可能是子进程,因此谁先运行不一定,这个由操作系统的调度器决定

  • 46
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 39
    评论
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

头发没有代码多

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值