当前位置: 首页 > news >正文

进程(Process)

一、概念

进程是操作系统资源分配的最小单元(文本段、数据段、系统数据段)

进程:就是程序执行的过程,包括创建、调度和消亡,是活的

程序:一段数据的集合,是死的

二、常用命令

三、进程的创建

1、进程的内存空间

        电脑会在硬件层为每个进程准备真实的内存空间

        在32位操作系统(有32根地址线)中,会为运行过程中的进程开辟0 - 4G虚拟内存空间

        在64位操作系统(有64根地址线)中,会为运行过程中的进程开辟0 - 8G虚拟内存空间

文本段

        存储代码和指令

数据段

        存储全局变量、静态变量、字符串常量,未经初始化变量值为0值

        在编译时分配空间,程序运行时,将a.out数据段加载到内存数据段中

        程序结束回收数据段空间

系统数据段 

        栈区:操作系统管理区域、存放局部变量、执行到变量定义时分配空间,超过变量 作用域回收变量空间,未经初始化为随机值

        堆区:程序员管理的区域,malloc申请、free释放

内核

        操作系统核心区域,用户无法访问,负责内存管理、CPU管理、硬件设备管理、进程管理、文件系统管理

 2、多个进程的存储

1. 进程的空间是独立的

2. 单核:一个CPU在同一时刻只能执行一个任务

3. 宏观并行,微观串行

4. 物理地址空间是独立的,虚拟地址空间共用同一份,所以多个进程并不是虚拟机地址空间相加

 四、进程的调度

1、宏观并行,围观串行

        多个进程在执行时总的看上去似乎是一起执行的,但实际是因为电脑依次处理每个进程时的速度较快导致的该现象,

        例如:父子两个进程并不是同时执行的,是有先后顺序的,谁先谁后不清楚

PCB(Process Control Block,进程控制块)

        操作系统内核管理进程的核心工具,它为进程的创建、执行、切换和终止提供了必要的信息和控制机制

MMU(Memory Management Unit,内存管理单元)

        计算机硬件中的一个重要组件,主要负责管理内存访问和虚拟内存与物理内存之间的地址转换

2、进程的状态

3、CPU调度任务规则

一个任务执行完毕后,如何选择下一个执行的任务?

 常见进程调度算法:

       a. 先来先执行,后来后执行

        b. 高优先级调度算法

        c. 时间片轮转调度算法

                时间片:CPU在某个进程任务中执行的一段时间

        d. 多级队列反馈

        e. 负载均衡调度算法

4、进程相关的函数接口

man 2 fork

pid_t fork(void);

功能:

        创建一个子进程

参数:

        缺省

返回值:

         成功在父进程中返回创建的子进程的PID

                在子进程中返回0

         失败返回-1

注意:
        1、子进程是父进程的不完全副本,会复制父进程的数据区、BSS区、堆区、栈区、参数和环境变量( 例一、例二),除了以上外还会复制输入输出缓冲区(例三)。       

        2、父进程结束,就会变成孤儿进程,孤儿进程会被1号进程(init)收养(例二)

例一 :

int mian(void)
{
    pid_t pid;

	 pid = fork();
     if (-1 == pid)
	{
		ERR_MSG("fail to fork");
		return -1;
	}
	if (0 == pid)
	{
		printf("子进程(PID:%d)执行!\n", getpid());
	}
	else if (pid > 0)
	{
		printf("父进程(PID:%d)执行!\n", getpid());
	}
	printf("都会执行!\n");

    return 0;
}

过程:结果:

例二: 创建一个父进程的2个子进程,要求子进程中打印自己的PID及父进程的PID,
            父进程中打印自己的PID及两个子进程的PID

父进程先结束,子进程成为孤儿进程

	pid_t pid;
	pid_t pid1;

	pid = fork();
	if (-1 == pid)
	{
		ERR_MSG("fail to fork");
		return -1;
	}
	if (0 == pid)
	{
		printf("子进程1  PID:%d  PPID:%d\n", getpid(), getppid());
	}
	else if (pid > 0)
	{
		pid1 = fork();
		if (-1 == pid1)
		{
			ERR_MSG("fail to fork");
			return -1;
		}
		if (0 == pid1)
		{
			printf("子进程2  PID:%d  PPID:%d\n", getpid(), getppid());
		}
		else if (pid1 > 0)
		{
			printf("父进程  PID:%d 子进程PID:%d %d\n", getpid(), pid, pid1);
		}
	}

子进程先结束,父进程不结束

	pid_t pid;
	pid_t pid1;

	pid = fork();
	if (-1 == pid)
	{
		ERR_MSG("fail to fork");
		return -1;
	}
	if (0 == pid)
	{
		printf("子进程1  PID:%d  PPID:%d\n", getpid(), getppid());
	}
	else if (pid > 0)
	{
		pid1 = fork();
		if (-1 == pid1)
		{
			ERR_MSG("fail to fork");
			return -1;
		}
		if (0 == pid1)
		{
			printf("子进程2  PID:%d  PPID:%d\n", getpid(), getppid());
		}
		else if (pid1 > 0)
		{
			printf("父进程  PID:%d 子进程PID:%d %d\n", getpid(), pid, pid1);
		}
	}

	while (1)
	{
		
	}

相关文章:

  • LLVM编译器简介
  • QUdpSocket的readyRead信号只触发一次
  • C++面试题,进程和线程方面(1)
  • Markdown 与富文本语法对照全解析
  • 使用Java爬虫获取1688 item_get_factory 接口的工厂档案信息
  • LLM+多智能体协作:基于CrewAI与DeepSeek的邮件自动化实践
  • PostgreSQL‘会用‘到‘精通‘,学习感悟
  • 《Keras 3 :使用 Vision Transformers 进行物体检测》
  • Qt开发⑥Qt常用控件_下_多元素控件+容器类控件+布局管理器
  • RabbitMQ 消息队列 优化发送邮件
  • 通信系统中物理层与网络层联系与区别
  • Linux下基于root指定用户执行命令的方法
  • OpenHarmony分布式数据管理子系统
  • JAVA-执行计划,表级锁,行级锁
  • Servlet概述(Ⅰ)
  • QT信号槽使用
  • 数据结构 之 【顺序表实现】(c语言实现)
  • Docker-技术架构演进之路
  • SpringBoot 整合 JPA
  • Redis多线程技术助力向量数据库性能飞跃
  • 建设银行网站查询工资/微信crm客户管理系统
  • 织梦中英文网站源码/网站免费网站免费优化优化
  • 网页游戏开服表最全/路由器优化大师
  • 做任务给佣金的网站有哪些/新人学会seo
  • 怀柔谁会网站开发/长沙seo排名优化公司
  • 建设网站/怎么下载有风险的软件