【linux】进程概念的介绍

什么是进程?进程的概念是什么?

对于操作系统来说:

进程是正在运行的程序

进程是可以分配处理器并由处理器执行的实体

而对于Linux内核来说:

进程是可担当分配系统资源的实体

如何描述一个进程

这里我们要介绍一下PCB了

PCB,全称为 进程控制块

PCB是用来标识一个进程的,它包含了该进程的各个信息

在Linux内核下,linux下的PCB是task_struct这个结构体

task_struct里面有哪些内容呢?

主要有以下几个:


进程的控制符

所谓的进程控制符,全称为Process Identifier,就是标识进程唯一的身份标识,所以也成为进程标识符

进程控制符有pid和ppid

pid表示进程的id

ppid表示父进程的id

每个进程都有非负的整数来表示唯一的进程ID,当一个进程终止后,其进程的ID就又可以被其他进程进行使用


每个进程除此之外还有其他的标识符

下列函数可以返回这些标识符


Linux下,C语言文件main.c是如何一步步成为进程的

Linux下的C语言成为可执行程序需要经历过四个步骤

分别是,预处理---编译---汇编---链接

(1)预处理要做的事情 --- 生成main.i 文件

- 1 、宏替换

- 2 、#include包含文件的展开

- 3 、去掉注释

- 4 、添加行号

- 5 、进行条件编译

(2)编译需要做的事情 --- 生成main.s文件

检查语法错误

(3)汇编需要做的事情 --- 生成main.o 文件

转化成二进制的机器码

(4)链接需要做的事情 --- 生成main.exe文件(按照Windows下可理解为.exe)

符号表的合并

从符号表中找到函数地址

程序转化为进程的过程

(1)内核将程序装入内存,为程序分配内存空间

(2)内核为该进程赋予PID以及各种信息,将进程放入运行队列中等待执行

什么是进程的内存映像

进程的内存映像是指内核在内存中如何存放可执行程序

布局如下:


进程的状态

进程具有七种状态

分别是RTSDZX和t


进程的优先级

进程的cpu资源的分配就是进程的优先级

如何查看进程的优先级?

首先呢,需要介绍如何查看系统进程

用指令

ps -l

之后,屏幕会输出以下几个内容


其中

UID 表示当前的用户身份情况(现在我的UID是500,切换到root下,UID为0)

PID 表示该进程的进程号

PPID 表示进程的父进程号

PRI 表示进程的优先级

NI 表示nice值,通俗的说,就是我们可以通过设置NI值来改变优先级PRI,当然,不是想改多少就改多少的

如何修改nice值?


如何创建一个进程

fork函数

头文件   #include<unistd.h>

pid_t fork(void);

作用:一个现有的进程调用fork函数可以创建一个子进程

返回值:子进程返回0,父进程返回进程的ID,出错会返回-1

说明:子进程是父进程的副本

注意:父进程不共享存储空间的部分,但是共享正文段

这里用到了写实拷贝,当父进程或者子进程进行修改的时候,内核只为要修改的区域的地方的内存制作一个副本

父进程和子进程的一些区别

1、fork()的返回值的不同,子进程返回0;父进程返回子进程的ID

2、进程的ID不同,其各自的父进程的ID不同

3、子进程的tms_utime,tms_stime,tms_cutime和tms_ustime均被设置为0

4、父进程的文件锁,不会被子进程继承

5、子进程的未处理闹钟会被清理

6、子进程的未处理信号集被设置为空值

什么是孤儿进程

所谓孤儿进程,就是在父进程创建子进程后,父进程先结束(进入X死亡状态)后,其创建的子进程便成了孤儿进程

我们都知道,当一个进程死亡时,其父进程会调用wait()或者waitpid()系统调用来处理子进程的信息

然而,孤儿进程由于其父进程率先死亡,因此必须要人领养

这个领养人是谁呢?

是1号进程,也就是init进程

孤儿进程的验证

测试代码

#include<stdio.h>
#include<sys/types.h>
int main()
{
	//利用fork()创建一个子进程
	pid_t id = fork();
	
	//根据返回值判断是子进程还是父进程
	if(id == 0)//child
	{
		//令进程一直执行,直到手动杀死
		while(1)
		{	
			sleep(1);
			printf("I'm child ... ");
			printf("child pid : %d , father : %d \n",getpid(),getppid());
		}
	}
	else//father
	{
		//运行过程中,手动杀死父进程
		while(1)
		{
			printf("I'm father!!!");
			printf("father pid : %d , grandfather : %d \n",getpid(),getppid());
			sleep(1);
		}
	}
	return 0;
}

令该程序跑起来

杀死父进程2260

观察子进程的信息变化


进程等待

wait()和waitpid()函数

函数作用:父进程用来获取已终止进程的退出状态,并彻底清除该进程

wait函数调用后的情况

1、若该进程的所有子进程都在运行,则wait阻塞

2、若该进程的一个进程结束了,则获取该结束进程的死亡信息,返回

3、若该进程没有子进程,则出错返回

什么是僵尸进程

僵尸进程指的是,在父进程没有死亡的时候,子进程死亡了,但是父进程还没处理子进程的死亡信息

此刻,子进程就是僵尸进程

僵尸进程的验证

测试代码

#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
int main()
{
	//创建子进程
	pid_t id = fork();

	if(id == 0)//child
	{
		printf("child ... %d  father ... %d\n",getpid(),getppid());
		exit(0);//子进程退出,成为僵尸进程
		sleep(20);//等待20秒,等待结束后从僵尸进程被真正灭亡
	}
	else//father
	{
		while(1)
		{
			printf("father ... %d  gfather ... %d\n",getpid(),getppid());
			sleep(1);
		}
	}
	return 0;
}

查看子进程和父进程的PID


查看子进程的状态


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值