解析进程复制:父子进程内存地址的神秘之处

news2024/12/26 9:20:43

当涉及到进程复制时,有时会出现一个令人困惑的现象:在父进程和子进程中,某些变量的内存地址似乎是相同的,尽管它们实际上是独立的进程。下面我将简单解释这个现象以及背后的原因。

进程复制:父子进程的神秘关系

在多进程编程中,使用 `fork()` 函数可以创建一个新的子进程。这个子进程是父进程的几乎完美副本,包括代码、数据和资源。这就是为什么在子进程中有时会看到父进程的某些变量具有相同的内存地址的原因。

为什么内存地址相同?

这种现象的原因在于虚拟内存系统。虚拟内存允许操作系统为每个进程创建一个独立的虚拟地址空间,使得每个进程都认为它在使用整个计算机的内存。但实际上,物理内存被分割和共享。

当调用 `fork()` 创建子进程时,操作系统并不会复制整个物理内存。相反,它会为子进程创建一个新的页表,该页表将虚拟地址映射到相同的物理内存页面。这就是为什么子进程看起来拥有与父进程相同的内存地址。

数据独立性

虽然父子进程共享相同的物理内存页面,但它们的数据是独立的。这意味着当一个进程修改共享页面上的数据时,不会影响到另一个进程。因为每个进程都有自己的页表,操作系统会根据页表来决定虚拟地址如何映射到物理内存。

进程间通信

尽管父子进程拥有相同的内存页面,但它们通常需要使用进程间通信(IPC)机制来实现数据共享。这可以通过管道、共享内存、消息队列等方式来实现。IPC 机制允许这两个进程在独立的虚拟地址空间中交换数据,确保数据的一致性和安全性。

结论

进程复制是多进程编程的常见技术,它允许创建独立运行的子进程,但在虚拟内存背后,这两个进程共享相同的物理内存页面。这种现象可以解释为什么父进程和子进程有时会看到某些变量的内存地址是相同的,尽管它们实际上是独立的进程。要确保数据的正确性和安全性,需要使用适当的 IPC 机制来实现进程间通信。对于开发者来说,了解虚拟内存系统和进程复制机制是编写稳健多进程应用程序的关键。

 demo案例

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void) 
{
	int fd[2];
	int ret;
    int status;

	//创建了两个字符数组 buff1 和 buff2,用于存储从父进程到子进程和从子进程到父进程的信息。
	char buff1[1024];
	char buff2[1024];
	pid_t pd;

	//调用 pipe(fd) 创建了一个管道,其中 fd 是一个包含两个文件描述符的数组,fd[0] 用于读取数据,fd[1] 用于写入数据。
	ret = pipe(fd);
	if (ret !=0) {
		printf("create pipe failed!\n");
		exit(1);
	}

	pd = fork();//调用 fork() 创建了一个子进程。如果 fork() 失败,程序将打印错误消息并退出。
	if (pd == -1) {
		printf("fork error!\n");
		exit(1);
	} else if (pd == 0) {//在子进程中(当 pd == 0 时),首先清空了 buff2,然后从管道的读取端 fd[0] 读取数据到 buff2 中。接着,子进程将一条信息写入管道的写入端 fd[1] 中,然后打印发送的信息和缓冲区地址。
		bzero(buff2, sizeof(buff2));
		read(fd[0], buff2, sizeof(buff2));
		printf("process(%d) received information[child-buff2]:%s  [%p]\n", getpid(), buff2,buff2);
		strcpy(buff1,"Hello!parent!");
        write(fd[1],buff1,strlen(buff1));
		printf("process(%d) send information[child-buff1]:%s  [%p]\n", getpid(), buff1,buff1);
	} else {//在父进程中(当 pd > 0 时),首先将一条信息写入管道的写入端 fd[1] 中,然后睡眠了5秒钟。接着,从管道的读取端 fd[0] 读取数据到 buff2 中,然后打印接收的信息和缓冲区地址。
		strcpy(buff1, "Hello!child");
		write(fd[1], buff1, strlen(buff1)); 
		printf("process(%d) send information[parent-buff1]:%s [%p]\n", getpid(), buff1,buff1);

		sleep(5);
        read(fd[0],buff2,sizeof(buff2));
		printf("process(%d) received information[parent-buff2]:%s [%p]\n", getpid(), buff2,buff2);
	}

	if (pd > 0) {
		wait(&status);//父进程等待子进程的结束(通过 wait(&status)),以确保子进程在父进程之前结束。
	}
	
	return 0;	
}

输出结果:结果表明,子进程和父进程中相同变量名的内存地址相同,但所存储的内容却并不一样。

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

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

相关文章

Vue3统一导出局部组件和全局组件

局部组件统一导出 components新增ComponentA.vue、ComponentB.vue两个组件 新增index.js进行组件统一导入 import ComponentA from ./ComponentA.vue import ComponentB from ./ComponentB.vueexport {ComponentA,ComponentB }使用 <template><ComponentA /><…

leetcode 150.逆波兰表达式求值

⭐️ 题目描述 &#x1f31f; leetcode链接&#xff1a;逆波兰表达式求值 思路&#xff1a; 假设这样一组表达式 { "2" , "1" , "" , "3" , "*" } 这是一种后缀表达式&#xff0c;首先我们准备一个栈&#xff0c;当如果不是…

电动汽车行业,这个技能绝了!

在当今不断演变的汽车工业中&#xff0c;电动汽车已经崭露头角&#xff0c;并迅速改变着我们的出行方式。这种创新的交通方式不仅减少了尾气排放&#xff0c;还为我们带来了更加环保和可持续的未来愿景。在电动汽车的核心&#xff0c;蓄电池技术正发挥着至关重要的作用。 然而&…

阿里巴巴推出D.Design文生图网站(免费10-20张图)

简介&#xff1a; d.design是阿里巴巴推出的一个基于人工智能的设计工具&#xff0c;可以帮助用户轻松创建3D模型和场景。该工具提供了丰富的素材库和功能&#xff0c;可以满足用户的各种需求。 ​堆友堆友是Alibaba Design打造的设计师全成长周期服务平台&#xff0c;围绕品质…

Python中处理异常和错误

作为一种强大且灵活的编程语言&#xff0c;Python 提供了许多机制来处理程序运行过程中可能出现的异常和错误。本文将详细介绍如何在 Python 中以“优雅、高效”的方式进行异常处理&#xff0c;并提供实用技巧帮助开发者更好地应对各种情况。无论您是初学者还是有经验的开发人员…

上行取消指示 DCI format 2_4

上篇介绍了DCI format 2_1的DL传输中断的内容&#xff0c;这篇就看下DCI format 2_4有关的UL 传输取消机制&#xff0c;值得注意的是这里的UL传输针对的是PUSCH和SRS传输。 UL cancellation DCI format 2_4相关机制引入的背景与DCI format 2_1一样&#xff0c;都是因为URLLC和e…

3ds max插件CG MAGIC中的室外功能可以高效出图吗?

使用3ds Max高效出图秘诀有没有什么秘诀呢&#xff1f;如何做到快速出图呢&#xff1f; 3ds max插件CG MAGIC中的室外功能可以高效出图吗&#xff1f; CG MAGIC 是一款基于3DS max深入开发的智能辅助设计插件。 自从CG Magic专业版上线之后&#xff0c;小伙伴们对新功能诀窍…

当浏览器切换到其他标签页或者最小化时,你的js定时器还准时吗?

最近一个项目遇到这个问题&#xff0c;获取北斗授时服务器时间校准本地时间&#xff0c;定时器是需要用到的&#xff0c;大致步骤分为以下几点&#xff1a; 1.定时请求服务器时间 2.根据获取到接口返回时间自动累加 参考&#xff1a; vue.js和原生js时间自动累加功能_js时间…

windows 下docker安装宝塔镜像 宝塔docker获取镜像

1. docker 安装宝塔 打开链接&#xff1a;https://www.docker.com/get-started&#xff0c;找对应的版本下载docker&#xff0c;安装docker打开百度云盘&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1DGIjpKkNDAmy4roaKGLA_w 提取码&#xff1a;u8bi 2. 设置镜像 点…

LeetCode刷题笔记【31】:动态规划专题-3(整数拆分、不同的二叉搜索树)

文章目录 前置知识343. 整数拆分题目描述解题思路代码进一步优化 96.不同的二叉搜索树题目描述解题思路代码优化改进 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【29】&#xff1a;动态规划专题-1&#xff08;斐波那契数、爬楼梯、使用最小花费爬楼梯&…

TikTok运营做不起来?IP是关键

作为跨境电商新蓝海&#xff0c;TikTok不断的加快自己推进电商业务的步伐&#xff0c;也吸引了越来越多的跨境商家入驻。但是很多人信心满满注册入驻后&#xff0c;却遇到了0播放&#xff0c;流量少&#xff0c;转化低的问题&#xff0c;Tiktok运营不起来&#xff0c;那你要注意…

手机上pdf转word的方法,快来掌握一下吧

在日常工作和学习中&#xff0c;我们常常需要将PDF文件转为Word文档以方便编辑和修改。本文将介绍手机上PDF转Word的方法及需要注意的事项。 PDF转Word的方法 目前市面上有很多PDF转Word的应用&#xff0c;通常都是在电脑上操作的&#xff0c;但是很多时候我们不在电脑前如果需…

形态图像处理

形态图像处理 预备知识 反射、平移结构元 腐蚀和膨胀 腐蚀 将 B 平移&#xff0c;当其原点位于 z 时&#xff0c;其包含在 A 中&#xff0c;则 z 为一个有效的位置&#xff0c;所有有效的z构成了腐蚀之后的结果腐蚀缩小或细化了二值图像中的物体可以将腐蚀看作形态学滤波操…

化繁为简,国内知名期货交易所依托 MogDB 数据库促信创改造项目提速

近年来&#xff0c;国家持续加大力度推动新基建建设&#xff0c;信创产业作为新基建的重要组成部分&#xff0c;在2020年得到全面推广。在这三年间里&#xff0c;我国信创产业逐步进入黄金发展期&#xff0c;国产基础软硬件从“不可用”到“可用”并逐渐向“好用”演进。因此&a…

Carla学习笔记(二)服务器跑carla,本地运行carla-ros-bridge并用rviz显示

一、服务器跑carla 详见Carla学习笔记&#xff08;一&#xff09;服务器跑carla本地显示窗口_Zero_979的博客-CSDN博客 只需要启动服务器端就行&#xff1a; ./CarlaUE4.sh -carla-rpc-port2000 -RenderOffScreen -graphicsadaper1 二、本地下载 carla-ros-bridge 官方库&…

手麻系统全套源码 术前、术中、术后全过程管理

手术麻醉临床信息系统源码 手麻系统全套源码 手术麻醉临床信息系统功能符合三级甲等医院评审要求&#xff0c;实现与医院现有信息系统如HIS、LIS、PACS、EMR等系统全面对接&#xff0c;全面覆盖从患者入院&#xff0c;经过术前、术中、术后&#xff0c;直至出院的全过程。通过…

C编程预备计算机专业知识

目录 cpu 内存条 硬盘 显卡 主板 显示器 之间的关系 什么是数据类型 基本数据类型 复合数据类型 什么是变量 变量为什么必须初始化&#xff0c;初始化就是赋值的意思 如何定义变量 什么是进制 常量在C语言中如何表示 常量以什么样的二进制代码存储在计算机中 什么是字节…

Ubuntu安装NVIDIA显卡驱动

目录 0. 引言1. 方法1 - 使用系统自带渠道安装2. 方法2 - 手动安装2.1. 卸载原有显卡驱动2.2. 安装显卡驱动2.3. 补救措施 0. 引言 \qquad 第一次入坑的建议看一下这部分。如果说要问我什么时候应该给Ubuntu装显卡驱动&#xff0c;我建议新系统用户第一件事就是安装显卡驱动&am…

C语言练习题解析:挑战与突破,开启编程新篇章!(3)

&#x1f493;博客主页&#xff1a;江池俊的博客⏩收录专栏&#xff1a;C语言刷题专栏&#x1f449;专栏推荐&#xff1a;✅C语言初阶之路 ✅C语言进阶之路&#x1f4bb;代码仓库&#xff1a;江池俊的代码仓库&#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐ 文…

如何加密Python程序

我们开发了一个项目&#xff0c;历尽艰辛&#xff0c;想发布出去&#xff0c;又怕别人窃取自己的劳动成果。 有效的方法一是可以上传github&#xff0c;分享源代码&#xff0c;其它想使用的朋友可以通过fork来进一步改进它。 对了&#xff0c;最近刚发现一个小技巧&#xff0…