[Linux进程概念]PCB进程初识

目录

一、什么是进程

1.课本概念

2.内核观点

二、进程的描述-PCB

1.什么是PCB

2.PCB的组织方式

3.task_struct是Linux操作系统下的PCB

4.task_struct内容分类

三、进程的查看

四、进程的创建

1.查看子进程id和父进程id

演示实例1:

2.fork初识

演示实例1:

演示实例2:


一、什么是进程

1.课本概念

进程是程序的一个执行实例,是操作系统对程序执行的基本单位

从不同角度,可以有不同的定义:

  • 进程是程序的一次执行过程
  • 进程是一个程序及其数据在处理机上顺序执行时所发生的活动
  • 进程是系统进行资源分配和调度的一个独立单位

2.内核观点

担当分配系统资源(CPU时间、内存)的实体


二、进程的描述-PCB

1.什么是PCB

  • 进程控制块(PCB)是操作系统为了管理和维护进程而设置的一个专门的数据结构。
  • 作用:PCB使一个在多道程序环境下不能独立运行的程序(含数据)成为一个能独立运行的基本单位,或与其他进程并发执行的进程。通过PCB,操作系统可以跟踪和控制每个进程的运行,并在需要时恢复进程的执行。

2.PCB的组织方式

  • 线性表方式:将所有的PCB连续地存放在内存的系统区,适用于系统中进程数目不多的情况
  • 索引表方式:系统按照进程的状态分别建立就绪索引表、阻塞索引表等,提高了查找特定PCB的效率
  • 链接表方式:系统按照进程的状态将进程的PCB组成队列,形成就绪队列、阻塞队列、运行队列等,具有灵活性高的优点,但查找特定PCB的效率较低
  • 数组方式:使用一个固定大小的数组来存储所有的PCB,通过索引来访问和操作PCB,提高了查找PCB的效率,但需要预先分配固定大小的数组空间
  • 树形结构方式:使用树的数据结构来管理PCB,每个PCB都作为一个节点,节点之间通过父子关系连接起来,可以灵活地组织PCB并提供更多的进程管理功能,但增加了复杂性

3.task_struct是Linux操作系统下的PCB

  • task_struct是Linux内核中的一种数据结构,它会被装载到RAM(内存)中并包含着进程信息

4.task_struct内容分类

task_struct结构体内部包含多个元素

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

三、进程的查看

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

这里只做简单介绍,细节内容后续说明

正在执行的进程的信息可以使用ps aux | grep test | grep -v grep指令查看

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{    
    while(1)
    {
        printf("1");
        sleep(1);
    }
    return 0;
}


四、进程的创建

1.查看子进程id和父进程id

  • getpid()函数和getppid()函数

演示实例1:

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

2.fork初识

fork() 是一个用于创建新进程的系统调用。当调用 fork() 时,它会创建一个与当前进程(称为父进程)几乎完全相同的子进程。新创建的子进程会从 fork() 系统调用的返回点开始执行,并且它拥有父进程的环境、打开的文件描述符、内存空间(但有自己的地址空间副本,采用写时复制机制)等。

演示实例1:

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

  • 这里可以看到原本一行的代码却输出了两行结果,这是为什么?
  • 这是由于fork()函数创建了一个子进程,打印结果第一行是父进程的pid和fork()返回值,第二行是子进程的pid和fork()返回值

演示实例2:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main()
{
	pid_t ret = fork();
	if(ret < 0)
	{
		perror("fork");
		return 1;
	}
	else if(ret == 0)
	{
		printf("我是子进程,我的pid是%d\n",getpid());
	}
	else
	{
		printf("我是父进程,我的pid是%d\n",getpid());
	}

	return 0;
}

  • 这里可以看到,根据fork()返回值的不同,会进入到不同的if语句中,从而再次印证fork()函数创建了不同于原来进程的新进程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值