理解进程、通过调用 fork 函数创建进程

news2025/7/19 12:23:03

文章目录

  • 1.理解进程
    • 1.1 CPU核的个数与进程数
    • 1.2 进程 ID
  • 2.通过调用 fork 函数创建进程
    • 2.1 fork.c

1.理解进程

进程(Process),其定义如下:“占用内存空间的正在运行的程序”。

假如各位从网上下载了 LBreakout 游戏并安装到硬盘。此时的游戏并非进程,而是程序。因为游戏并未进入运行状态。下面开始运行程序。此时游戏被加载到主内存并进入运行状态,这时才可称为进程。如果同时运行多个 LBreakout 程序,则会生成相应数量的进程,也会占用相应进程数的内存空间。

再举个例子。假设各位需要进行文档相关操作,这时应打开文档编辑软件。如果工作的同时还想听音乐,应打开 MP3 播放器。另外,为了与朋友聊天,再打开 MSN 软件。此时共创建 3 3 3 个进程。从操作系统的角度看,进程是程序流的基本单位,若创建多个进程,则操作系统将同时运行。有时一个程序运行过程中也会产生多个进程。接下来要创建的多进程服务器就是其中的代表。

1.1 CPU核的个数与进程数

拥有 2 2 2 个运算设备的 CPU 称作双核(Daul)CPU,拥有 4 4 4 个运算器的 CPU 称作四核(Quad)CPU。也就是说, 1 1 1 个 CPU 中可能包含多个运算设备(核)。核的个数与可同时运行的进程数相同。相反,若进程数超过核数,进程将分时使用 CPU 资源。但因为 CPU 运转速度极快,我们会感到所有进程同时运行。当然,核数越多,这种感觉越明显。

1.2 进程 ID

无论进程是如何创建的,所有进程都会从操作系统分配到 ID。此 ID 称为“进程ID”,其值为大于 2 2 2 的整数。 1 1 1 要分配给操作系统启动后的首个进程(用于协助操作系统),因此用户进程无法得到 ID 值 1 1 1

观察 Linux 中正在运行的进程:

ps au

在这里插入图片描述

可以看出,通过 ps 指令可以查看当前运行的所有进程。特别需要注意的是,该命令同时列出了 PID(进程ID)。另外,上述示例通过指定 au 参数列出了所有进程详细信息。

2.通过调用 fork 函数创建进程

#include <unistd.h>

pid_t fork(void);

// 成功时返回进程ID,失败时返回-1

fork 函数将创建调用的进程副本。也就是说,并非根据完全不同的程序创建进程,而是复制正在运行的、调用 fork 函数的进程。另外,两个进程都将执行 fork 函数调用后的语句(准确地说是在 fork 函数返回后)。但因为通过同一个进程、复制相同的内存空间,之后的程序流要根据 fork 函数的返回值加以区分,即利用 fork 函数的如下特点区分程序执行流程:

  • 父进程:fork 函数返回子进程 ID。
  • 子进程:fork 函数返回 0 0 0

此处父进程(Parent Process)指原进程,即调用 fork 函数的主体,而子进程(Child Process)是通过父进程调用 fork 函数复制出的进程。

接下来讲解调用 fork 函数后的程序运行流程,如下图所示。

在这里插入图片描述

从上图可以看到,父进程调用 fork 函数的同时复制出子进程,并分别得到 fork 函数的返回值。但复制前,父进程将全局变量 gval 增加到 11 11 11,将局部变量 lval 的值增加到 25 25 25,因此在这种状态下完成进程复制。复制完成后根据 fork 函数的返回类型区分父子进程。父进程将 lval 的值加 1 1 1,但这不会影响子进程的 lval 值。同样,子进程将 gval 的值加 1 1 1 也不会影响到父进程的 gval。因为 fork 函数调用后分成了完全不同的进程,只是二者共享同一代码而已。

2.1 fork.c

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

int gval = 10;

int main(int argc, char *argv[])
{
	pid_t pid;
	int lval = 20;
	gval++;
	lval += 5;
	
	// 创建子进程。对于父进程来说,fork函数返回子进程ID;对于子进程来说,fork函数返回0。
	pid = fork();

	if (pid == 0)    // if Child Process
	{
		gval += 2;
		lval += 2;
	}
	else    // if Parent Process
	{
		gval -= 2;
		lval -= 2;
	}
	
	if (pid == 0)
		printf("Child Proc: [%d, %d]\n", gval, lval);
	else
		printf("Parent Proc: [%d, %d]\n", gval, lval);

	return 0;
}

编译运行:

gcc fork.c -o fork
./fork

输出结果:

Parent Proc: [9, 23]
Child Proc: [13, 27]

从运行结果可以看出,调用 fork 函数后,父子进程拥有完全独立的内存结构。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/395524.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CS项目实训-Java 银行ATM机

摘 要 本次课程设计主要目的是培养我们面向对象软件开发的思维&#xff0c;初步了解软件开发的一般流程。提高编程的实际动手能力并增强大家对面向对象的了解。这次课程设计的主要内容是开发一个应用程序&#xff0c;我们小组设计的ATM柜员机&#xff0c;它主要是由各个indows窗…

05 | 如何安全、快速地接入OAuth 2.0?

05 | 如何安全、快速地接入OAuth 2.0&#xff1f; 构建第三方软件应用 第一点&#xff0c;注册信息 小兔软件的研发人员提前登录到京东商家开放平台进行手动注册&#xff0c;以便后续使用这些注册的相关信息来请求访问令牌。兔软件需要先拥有自己的 app_id 和 app_serect 等信…

联想笔记本电脑开机后一直转圈无法启动怎么办?

联想笔记本电脑开机后一直转圈无法启动怎么办&#xff1f;在正常开启电脑的过程中&#xff0c;系统进入到加载页面&#xff0c;但是却一直无法正常的启动。进行系统的重新启动依然是无法正常的使用。遇到这个情况需要进行系统的重置。接下来我们来看看详细的解决方法分享吧。 准…

实现用户操作日志记录

Java记录操作日志 java自带的日志框架是java.util.logging&#xff08;JUL&#xff09;&#xff0c;从JDK1.4&#xff08;2002&#xff09;开始捆绑在JDK中。可以使用JUL来记录操作日志。以下是使用JUL记录事务的示例&#xff1a; // java.util.logging java.util.logging.Lo…

网分线缆测试和dc-block

今天的好苹果和坏苹果 好苹果&#xff1a;是校准件和网分都是好的&#xff0c;又给了我一次复盘的机会 网分测试线缆&#xff1a; 1.网分直接复位&#xff0c;如果网分复位是校准状态&#xff0c;且解的是精密转接头&#xff0c;BNC的&#xff0c;可以不校准&#xff0c;结果差…

【高中数学教资】教案设计通用模板

前言 本文针对的是高中数学教师资格证笔试中最后的大题——教案设计&#xff08;含设计意图&#xff0c;文末有2022下半年高中数学教资教案设计大题&#xff09;。并附上高中数学404教资考点大纲&#xff0c;还有在学习中发现的一些可以免费学习网站推荐。 一、高中数学404考…

List系列集合

一. List集合特点、特有API List的实现类的底层原理 ArrayList底层是基于数组实现的&#xff1a;根据索引定位元素快&#xff0c;增删相对慢。LinkedList底层基于双链表实现的&#xff1a;查询元素慢&#xff0c;增删首尾元素是非常快的。public class ListDemo01 {public sta…

SerDes---CDR技术

1、为什么需要CDR 时钟数据恢复主要完成两个工作&#xff0c;一个是时钟恢复&#xff0c;一个是数据重定时&#xff0c;也就是数据的恢复。时钟恢复主要是从接收到的 NRZ&#xff08;非归零码&#xff09;码中将嵌入在数据中的时钟信息提取出来。 2、CDR种类 PLL-Based CDROve…

【信号与系统笔记】第一章 绪论

1.1信号传输系统 信息传输的任务 将带有信息的信号&#xff0c;通过某种系统由发送者传送给接收者。 通信系统的组成 转换器&#xff1a;把消息转换为电信号或者把电信号还原成消息信道&#xff1a;信号传输的通道&#xff0c;广义上来说。发射机和接收机也可以是信道的一部分…

【RabbitMQ】Producer之publisher confirm、transaction - 基于AMQP 0-9-1(二)

上篇文章主要介绍Producer的mandatory参数&#xff0c;备份队列和TTL的内容&#xff0c;这篇文章讲继续介绍Producer端的开发&#xff0c;主要包括发布方确认和事务机制。 发布方确认 消息持久化机制可以保证应服务器出现异常导致消息丢失的问题&#xff0c;但是Producer将消…

线程池ThreadPoolExecutor,从0到0.6

ThreadPoolExecutor是JDK提供的在java.util.concurrent包中的一个用于创建线程池的工具类。 一、ThreadPoolExecutor的7个参数 corePoolSize&#xff1a;核心线程数&#xff0c;线程池中保留的最小的线程数量&#xff0c;即使它们是空闲的也不会被销毁&#xff0c;除非allowCor…

Modbus转profinet网关连接1200PLC在博图组态与驱动器通讯程序案例

本案例给大家介绍由兴达易控modbus转profinet网关连接1200PLC在博图软件无需编程&#xff0c;实现1200Profinet转modbus与驱动器通讯的程序案例 硬件连接&#xff1a;1200PLC一台&#xff1b;英威腾DA180系列驱动器一台&#xff1b;兴达易控modbus转profinet网关一台 下面就是…

【Git】拉取 Pull Requests 测试的两种方法

文章目录前言参考目录方法说明方法一&#xff1a;直接拉取方法二&#xff1a;使用 diff 文件2.1、保存 diff 文件2.2、新建分支并执行文件前言 最近有参与到框架帮忙进行简单的 Pull Requests&#xff08;以下简称 PR&#xff09; 测试&#xff0c;因为也是第一次接触到这种操…

代码随想录 动态规划||01背包理论 416

Day3601背包理论基础01背包有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#xff0c;求解将哪些物品装入背包里物品价值总和最大。暴力的解法是指数级别的时间复杂度。进而才需要动态规划的解法来…

Java学习笔记 --- Servlet(1)

一、Servlet技术 1、Servlet基本介绍 1、Servlet 是 JavaEE 规范之一。规范就是接口 2、Servlet 就 JavaWeb 三大组件之一。三大组件分别是&#xff1a;Servlet 程序、Filter 过滤器、Listener 监听器。 3、Servlet 是运行在服务器上的一个 java 小程序&#xff0c;它可以…

院士交锋,专家论道|NLP大模型技术与应用十大挑战,剑指AI未来

2023年2月24日下午&#xff0c;第四届OpenI/O启智开发者大会NLP大模型分论坛在深圳人才研修院隆重举办。NLP大模型论坛会议现场众多NLP领域顶级专家学者与多家国产NLP大模型开发团队汇聚一堂&#xff0c;学术界与产业界破圈交流&#xff0c;激荡尖端思想、分享前沿动态&#xf…

Linux学习第二十二节-网卡IP设置

1.修改网卡IP地址 方式一&#xff1a;通过修改网卡配置文件修改 网卡配置文件位置&#xff1a; /etc/sysconfig/network-scripts/网卡名 #ifconfig 表示用于显示和设置网卡的参数 #ip addr 表示用于显示和设置网卡的参数 #systemctl restart network 表示重启网络 …

Spark Join大小表

Spark Join大小表无法广播过滤后大小表数据分布均匀大小表 : 大小表尺寸相差 3 倍以上 Join 优先考虑 BHJ小表的数据量 > 广播阈值时&#xff0c;优先考虑 SHJ 无法广播 大表 100GB、小表 10GB&#xff0c;都远超广播变量阈值 当小表的尺寸 > 8GB时&#xff0c;创建广…

剑指-Offer-30-包含min函数的栈

剑指 Offer 30.包含min函数的栈 题目描述&#xff1a; 定义栈的数据结构&#xff0c;请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中&#xff0c;调用 min、push 及 pop 的时间复杂度都是 O(1)。 示例&#xff1a; MinStack minStack new MinStack(); minSt…

Python中的错误是什么,Python中有哪些错误

7.1 错误(errors) 由于Python代码通常是人类编写的&#xff0c;那么无论代码是在解释之前还是运行之后&#xff0c;或多或少总会出现一些问题。 在Python代码解释时遇到的问题称为错误&#xff0c;通常是语法和缩进问题导致的&#xff0c;这些错误会导致代码无法通过解释器的解…