[ Linux ] 进程概念,pcb,查看进程,pid,ppid,fork

目录

1. 进程

1.1 基本概念

1.2 描述进程 - PCB 

1.3 查看进程

1.3.1 第一种方式

1.3.2 第二种方式

1.4 通过系统调用获取进程标识符

1.4.1 获取进程的pid

1.4.1 ppid

1.5 创建子进程


1. 进程

1.1 基本概念

  • 课本概念:程序的一个执行实例,正在执行的程序等。
  • 内核观点:担当分配系统资源(CPU时间,内存)的实体。

什么是程序的一个执行实例呢,我们在win系统中可以理解为正在运行的一个程序,那程序和进程有什么区别呢?我们可以打开任务管理器查看正在运行的进程。在内核观点中,一个需要系统分配资源(CPU时间,内存)的实体就是一个进程。

我们可以理解为 进程 = 可执行程序+对应的tast_struct(PCB)

1.2 描述进程 - PCB 

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

为什么管理进程要有PCB?

因为操作系统要管理进程,必须先描述再组织,因此每个进程都要有PCB(是操作系统管理描述的结构体类型)

我们可以看看Linux内核源代码(2.6版本),这个结构体非常大!

task_struct-PCB的一种

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

1.3 查看进程

1.3.1 第一种方式

我们在Linux下写一个简单的写循环C代码,我们可以使用这条命令系统进程

ps axj

C程序

#include <stdio.h>
#include <unistd.h>

int main()
{
  while(1)
  {
   printf("这是一个进程\n");
   sleep(1);

  }
  return 0;
}

我们要想查看mytest的进程输入这条指令

ps ajx | grep mytest.c

 

1.3.2 第二种方式

进程信息可以通过/proc系统文件夹查看。proc内有当前系统实时的进程信息!


我们进入proc文件夹,发现内部有许多蓝色的东西,这些是什么呢?

 这些蓝色的东西叫做进程的pid,每一个进程在系统中都会存在一个唯一的标识符!就如同我们在学校都有一个唯一的学号,这个标识符就是pid!

我们首先通过下面指令找到我们这段C语言的pid 

ps ajx | head -1 && ps ajx | grep 'mytest' | grep -v grep

此时我们进入proc文件夹 查找pid为2670的进程,我们说proc下是实时的进程信息,因此我们让C语言程序运行起来时,我们应该可以找到这个路径

 

当我们终止C程序时,根据实时查找我们应该无法查找到该路径

 

 

注:每次程序启动时的进程pid可能不同。

 

1.4 通过系统调用获取进程标识符

  • 进程id(pid)
  • 父进程(ppid)

我们在刚刚查看进程时,我们发现pid前还有一个ppid,那么pid 这些东西都在哪里呢?

这些都是进程的内部属性! 属性是数据,因此这些所有东西都在进程的进程控制块中(PCB)tast_struct结构体中。

1.4.1 获取进程的pid

我们可以使用man帮助手册查看getpid

man 2 getpid

 我们通过C程序查看pid

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
  while(1)
  {
  printf("这是一个进程 pid = %d \n",getpid() );
  sleep(1);
  }
  return 0;
}

C程序运行结果 

系统查看PID

我们在Linux中要终止一个程序可以使用ctrl+C,我们学习了进程之后,如果一旦获取到进程的pid,我们也可以通过kill命令杀掉该进程(其中-9 为9号信号)

kill -9 [进程pid]

 

1.4.1 ppid

我们首先获取一个ppid,我们使用C程序来打印

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main()
{
  while(1)
  {
  printf("这是一个进程 pid = %d,ppid = %d \n",getpid(),getppid());
  sleep(1);
  }
  return 0;
}

我们也可以也可以通过指令查一下

我们多次启动该进程发现ppid不发生变化,而pid一直在变

 

 

 

我们使用指令查看一下该进程发现是一个bash。几乎我们在命令行上所执行的所有的指令(你的cmd)都是bash进程的子进程!

ps ajx | head -1 && ps ajx | grep 7670

1.5 创建子进程

我们创建进程有很多方法 现在我们知道./运行程序可以创建,我们也可以通过代码创建子进程fork(),首先我们使用man手册看一下fork的使用方法

fork有两个返回值

fork函数是用来创建子进程的,它有两个返回值

父进程返回子进程的pid,给子进程返回0

首先我们写一段C程序来验证一下fork函数有两个返回值

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  pid_t id = fork();
  
  printf("hello fork\n");
  sleep(1);

  return 0;
}

运行这段程序我们发现hello fork打印了两遍,我们明明在程序中只写了一个printf函数,怎么会有两个hello fork打印结果呢?

再次我们对代码进行修改

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  pid_t id = fork();
  
  printf("hello fork! id = %d\n",id);
  sleep(1);

  return 0;
}

我们查看这段编译的结果,我们查看id的结果居然都不同!在C语言中怎么可能一个id有两个不同的值呢?这个问题我们暂时回答不了,当我们学习完进程地址空间中再来回答。

此时我们知道了id为0是子进程,id大于0是父进程,此时我们写一段程序来查看一下

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main()
{
  pid_t id = fork();
  
  //id:0子进程  >0是父进程
  if(id == 0)
  {
    //子进程
    while(1)
    {
     printf("我是子进程,我的pid:%d,我的父进程是:%d\n",getpid(),getppid());
     sleep(1);
    }
  }
  else
  {
    //父进程
    while(1)
    {
    printf("我是父进程,我的pid:%d,我的父进程是:%d\n",getpid(),getppid());
    sleep(1);
    }
  }
  //binprintf("hello fork! id = %d\n",id);
  // sleep(1);
  return 0;
}

我们在C语言中,if和else可以同时进行吗,两个while循环可以同时进行吗?

我们通过打印这段代码发现 这些都是可能的!!!

结论:

  • fork之后,父进程和子进程会共享代码,一般会执行后续的代码 -- printf为什么会打印两次的问题
  • fork之后,父进程和子进程返回值不同,可以通过不同的返回值,判断,让父子执行不同的代码块!

为什么fork()给父进程返回子进程的pid,给子进程返回0?

在现实生活中,父亲:儿子 = 1:n(n>=1)父亲为了区别儿子,会给儿子起不同的名字。类比到这里就是父进程必须有标识子进程的方案,fork之后,给父进程返回子进程的pid!

子进程最重要的是要知道自己被创建成功了,因为子进程找父进程的成本非常低(直接getppid())

为什么fork()会返回两次?

fork()函数是OS提供的系统调用接口(OS system call),fork之后,OS做了什么?父进程有自己的tast_struct+父进程的代码和数据,创建进程系统多了一个进程,子进程也应该有自己的tast_struct+子进程的代码和数据。

子进程的tast_struct 对象内部的数据从哪里来呢?--》基本是从父进程继承下来的。子进程执行代码,计算数据的,子进程的代码从哪里来呢?--》 子进程和父进程执行同样的代码,父子进程代码共享!而数据要各自独立(比如pid一定不同)

虽然代码相同,但是可以通过不同的返回值,可以执行不同的代码。

(本篇完)

  • 16
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小白又菜

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

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

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

打赏作者

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

抵扣说明:

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

余额充值