本节目录

  • 1.一个重要的管理理念
  • 2.进程的概念理解
  • 3.描述进程 - PCB?
  • 4.查看进程
  • 5.通过系统调用获取标示符
  • 6.通过系统调用创建进程-fork初识


1.一个重要的管理理念

我们在做软件开发时,大家要时刻记起一个管理理念:先描述,在组织

linux 查看top进程 执行程序目录 docker_数据

如上,在银行系统中,比如行长想对2015年之前的电脑进行更新,则管电脑设备的IT部门部长对电脑的年限进行报表,然后行长根据报表,给IT部门拨一份预算,进行更新。这里行长并不是直接对电脑设备进行管理,而是通过IT部长拿到电脑的数据,然后对数据进行管理,也就是先对需要管理的东西进行描述,这里描述是将电脑设备的年限数据拿到,然后将其放到某种数据结构中进行管理。

操作系统对底层的硬件和上层的软件的管理本质也是这个,先描述,在组织。

这里大家发现,不管是银行系统,还是操作系统,它们都假设对所有人都是不值得信任的,但又要给用户提供服务,所以开了一个个柜台,一个个接口。为什么呢?1.安全,维护内部信息,如果用户对操作系统不够了解,直接对它的底层进行操作可能会导致操作系统崩溃。
2.用户直接对操作系统底层进行操作,成本较高,这样可以提高效率,减少过度消耗。

除了开一个个柜台,银行还会在柜台之上设立服务层,对不会柜台给他的表啊等进行辅助说明,帮助其完成想要的手续。
同样,操作系统也有类似的,有些系统接口在使用上比较难,所以会对接口进行封装,在接口之上会有先shell外壳,图形化界面,第三方库(C库,C++库,boost库等)等,方便用户进行使用系统资源。

2.进程的概念理解

其实,我们自己启动一个软件,,本质就是启动了一个进程!
在linux操作系统中,运行一条命令,./XXX,运行的时候,其实就是在系统层面创建了一个进程!!!
Linux是可以同时加载多个程序的,Linux是可能同时存在大量的进程在系统中的(OS,内存)
Linux系统要不要管理进程呢?必须的!
Linux系统是如何管理进程的呢?先描述,在组织。

举个例子:我们在磁盘中写了一个test.c文件,编译链接生成test.exe文件,它包含代码和数据,然后将其加载到内存中,再给给CPU进行执行,我们知道可能有很多个程序被加载到内存中,此时它们的名字叫进程,那么内存或者说操作系统要不要对它们进行管理呢,答案是肯定的,如何管理,这不得不谈及那六子真言,先描述,在组织。(文件 = 内容+属性)

操作系统给每个加载到内存的进程创建了一个PCB结构体,它包含了进程所有的属性。

struct
{
	//属性数据,进程全部的属性数据
	//struct PCB* next;
	//struct PCB* prev;
}

如何理解属性?
人认识世界是通过属性来认识的,属性是数据,比如它知道程序的代码放在何处,数据在何处,当前处于什么状态,进程的优先级如何等等。
如此一来,操作系统对进程的管理,变成了对进程PCB结构体链表的增删查改。(这里的链表是双向链表)

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

3.描述进程 - PCB?

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

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

task_struct内容分类
标示符:描述本进程的唯一标识符,用来区别其他进程。(PID)
状态:任务状态,退出代码,退出信号等。
优先级:相对于其他进程的优先级。
程序计数器:程序中即将被执行的下一条指令的地址。(寄存器)
内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
上下文数据:进程执行时处理器的寄存器中的数据,后面详细介绍。
I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
记账信息:可能包括处理器时间总和,使用的时钟树综总和,时间限制,记账号等。
其他信息

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

4.查看进程

进程的信息可以通过/proc系统文件夹查看

如:要获取PID为1的进程信息,你需要查看/proc/1这个文件夹

大多数进程信息同样可以使用top和ps这些用户级工具来获取

linux 查看top进程 执行程序目录 docker_服务器_02


myproc.c

1 #include <stdio.h>
  2 #include <unistd.h>
  3 
  4 int main()
  5 {
  6   while(1)
  7   {
  8     printf("hello world!\n");
  9     sleep(1);
 10   }
 11   return 0;
 12 }

linux 查看top进程 执行程序目录 docker_#include_03


通过上面我们发现myproc.c进程的PTD为19845,我们也可以通过这个查看此进程的内容信息

类似方法为

linux 查看top进程 执行程序目录 docker_服务器_04

linux 查看top进程 执行程序目录 docker_linux_05


cwd(current working directory):当前进程的工作目录!

bin->运行的->每个进程都会有一个属性,来保存自己所在的工作路径。

exe表示这个进程是一个.exe文件。

5.通过系统调用获取标示符

进程id(PID)
父进程id(PPID)

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
 printf("pid: %d\n", getpid());
 printf("ppid: %d\n", getppid());
 return 0;
}

linux 查看top进程 执行程序目录 docker_数据_06


进程有它的pid,同样也有它的ppid(父进程),像ls,pwd,./myproc等等,它们的父进程就是bash,即命令行解释器,可以想象bash的父进程应该是操作系统。

6.通过系统调用创建进程-fork初识

linux 查看top进程 执行程序目录 docker_服务器_07


linux 查看top进程 执行程序目录 docker_运维_08

[jyf@VM-12-14-centos 进程]$ ./myproc
I am parent process:pid :24766
ret:24767,pid:24766,ppid:17172
ret:0,pid:24767,ppid:24766
[jyf@VM-12-14-centos 进程]$ cat myproc.c
#include <stdio.h>
#include <unistd.h>

int main()
{
   printf("I am parent process:pid :%d\n",getpid());

   pid_t ret = fork();
   //变成两个进程,一个是父进程,一个是子进程
   printf("ret:%d,pid:%d,ppid:%d\n",ret,getpid(),getppid());
   sleep(1);





//   while(1)
//  {
//   printf("hello world! pid:%d\n",getpid());
//   sleep(1);
//  }
  return 0;
}
[jyf@VM-12-14-centos 进程]$

下篇文章继续接着这里进行讲解!期待与你相遇。