Linux程序的地址空间,进程终止

个人主页:点我进入主页

专栏分类:C语言初阶  C语言进阶  数据结构初阶    Linux    C++初阶    算法

欢迎大家点赞,评论,收藏。

一起努力,一起奔赴大厂

一.程序的地址空间

1.1程序的地址空间的引入

        我们知道frok可以创建子进程,子进程会继承父进程的大部分属性,如果我们我们给出一个g_val,在子进程和父进程中输入g_val的值以及g_val的地址,会是怎样的结果呢?我们看下面代码:

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

int main()
{
    int g_val=100;
    pid_t id=fork();
    if(id==0)
    {
        int cnt=5;
        while(cnt--)
        {
            printf("I an child process,g_val=%d,&g_val=%p,pid=%d, ppid=%d\n",g_val,&g_val,getpid(),getppid());
            sleep(1);
        }
    }
    else if(id>0)
    {
        while(1)
        {
            printf("I an father process,g_val=%d,&g_val=%p,pid=%d, ppid=%d\n",g_val,&g_val,getpid(),getppid());
            sleep(1);
        }
    }
    return 0;
} 

我们运行后可以看到

父进程的g_val的地址和子进程的g_val的地址相同 ,如果我们,我们将子进程的代码修改,每次让g_val的值加1,会是怎样的结果?我们可以看到一下

g_val的值不同,但是g_val的地址却一样,这是为什么呢?在c语言时我们知道一个地址对应一个值,为什么在这里会出现一个地址对应两个值?这打破了我们的常规认知,其实不然,在以前我们写的都是一个进程,在这里是两个进程,这其中自然有一些差别,那这是如何实现的呢?这与程序的地址空间有关,这里的地址也不是物理地址,是虚拟地址

1.2程序地址空间概图

1.2.1不修改值时

        程序的地址空间是怎样的呢?我们可以看下面的图

 父进程有一个g_val虚拟地址是0x7ffe258b87bc,在父进程的地址空间中会有个初始化数据,里面的g_val地址也是虚拟地址,同时还有一个页表,页表有两部分,一部分是虚拟地址,一部分是物理地址,它相当于一个映射进程的虚拟地址对应者相应的物理地址。由于子进程会继承父进程的代码和数据以及大部分属性,所以子进程会继承父进程的task_struct,继承父进程的地址空间,父进程的页表,也就是说会进程一次浅拷贝

1.2.2修改值时

        在上面我们有一个修改g_val的值,那它和上面的过程一样吗?事实上是类似的,当我们想要修改值时,会发生一次写时拷贝,写时拷贝是什么呢?写的时候再进程修改,我们看下面的图

 子进程会将父进程的代码。数据。mm_struct,task_struct进行拷贝,在物理空间中重新开辟一次g_val进行写。

1.3理解地址空间

        进程有独立的地址空间,独立的页表,如果父进程和子进程不写,一个全局变量(类似于g_val的变量),默认会被子进程和父进程共享(只读)。那为什么这样干呢?如果我们不采用写时拷贝,只要有一个子进程就会在物理内存上开辟一块空间,这样有一定的缺点,有时候我们并不会修改值,会造成没有意义的空间开辟,那我们采用写时拷贝会不会很慢呢?当然不会,我们开辟的时候就拷贝,和用的时候再拷贝,我们采用写时拷贝还会减少拷贝的次数,效率更快,更节省空间,写时拷贝就是我都你不会用

1.3.1为什么要有地址空间(地址空间的优点)

        首先页表和地址空间可以将无序变为有序,我们知道我们开辟的空间是随机开辟的,通过页表的映射关系可以有效的将空间变得有序。其次可以将进程管理模块(页表和地址空间)和内存模块(物理空间)解耦,在程序进程检测时它检测到地址空间有就可以进行执行,因此我们只在地址空间上申请内存,填写页表的左侧,用的时候再在物理空间上开辟内存,这样也是可以的,还有一种情况我们先看下面的图:

假如 我们有2MB的内存,我们映射到物理空间上后,可以先执行1MB的内存,当者1MB执行完后可以先将这1MB内存释放,删除页表的关系,但是地址空间不变,这样我们看着还是2MB。最后访问越界时,如果页表中查不到这个地址,os就会阻止这个请求,实现对物理内存的保护,例如我们一个数组a[10],我们访问a[200]就会被os拦截。

1.3.2进一步理解页表和写时拷贝

        在页表中不仅仅有虚拟地址和物理地址这两部分,还有一个检测是否在内存中以及权限,我们先说是否在内存中,它用一个0个1来表示0不在内存中,1在内存中,那什么时候会显示0呢?

当内存不足时,会将一部分页表的内容唤出到磁盘中,还记得我们进程挂起的swap分区吗,这里和那个类似,当被唤出到磁盘中后这里就会显示为0 。

当我们创建子进程后父进程和子进程中 权限都会被修改为r,当我们想要修改时发生写时拷贝,权限修改为w。当操作系统检测到错误时会先进行检测是否不在物理内存中(缺页中断,也就是页表中为0),然后检测是否需要发生写时拷贝(检测权限是否为r),都不是才进程异常处理

二.进程的终止

2.1进程终止的3中状态

2.1.1代码跑完结果正确

我们先运行下面代码

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

int main()
{
    printf("pid=%d,ppid=%d\n",getpid(),getppid());
    return 0;
} 

运行后输入指令

echo $?

echo $?是返回我们前一个程序的返回码,我们将上面代码return 100然后运行然后输入指令echo$?可以看到

当我们再执行一次ehco $?可以看到

这是输出echo $?的退出码。

2.2.1代码跑完,结果错误

        在这里我们需要先知道退出码有什么作用,在一个父进程中我们需要知道子进程的退出状态,是成功还是失败?失败的原因是什么?所以出现了退出码这个概念。退出码有很多我们需要知道每一个退出码是什么吗?其实不需要,我们有一个函数可以知道每个退出码是什么意思,我们看下面代码

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

int main()
{
    for(int errorcode=0;errorcode<=255;errorcode++)
    {
        printf("errorcode=%d->%s\n",errorcode,strerror(errorcode));
    }
    printf("pid:%d,ppid=%d\n",getpid(),getppid());
    return 0;
} 

我们运行代码

2.2.3出现异常

        运行时,进程崩溃了,os会将进程杀掉一旦出现了异常退出码就没有意义了,为什么出现异常原因是进程出现了异常,本质说os进程发出信号。例如我们运行下面代码:

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

int main()
{
    while(1)
    {
        printf("pid=%d,ppid=%d\n",getpid(),getppid());
        sleep(1);
    }
    return 0;
} 

我们输入指令

kill -9 pid

可以看到

我们可以输入指令

kill -11 pid

2.2检测进程终止顺序

        首先检测进程是否出现异常,出现异常就不用管退出码,如果出现退出码,代码一定跑完了,再看退出码,异常后退出码是什么都没有任何意义。所以衡量一个进程退出我们只需要知道程序的退出码和推出信号。在进程的task_struct中有一个退出码和一个推出信号,当进程结束时会将这个给父进程。

2.3进程如何终止(exit和_exit)

        首先可以通过return实现进程终止。也可以通过exit来实现进程终止,exit在结束时会冲刷一次缓冲区,我们运行下面代码

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

int main()
{
    printf("hello process.exe\n");
    printf("exit");
    exit(0);
} 

运行后可以看到

两个都输出了。

还有一种是_exit函数,我们看下面代码

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

int main()
{
    printf("hello process.exe\n");
    printf("exit");
    _exit(0);
} 

运行后

我们可以看到exit会冲刷一次缓冲区,_exit不会冲刷缓冲区。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

重塑我们对随机性在计算中的作用的理解

2023年图灵奖&#xff0c;最近刚刚颁给普林斯顿数学教授 Avi Wigderson&#xff01;作为理论计算机科学领域的领军人物&#xff0c;他对于理解计算中的随机性和伪随机性的作用&#xff0c;作出了开创性贡献。 Avi Wigderson 的履历 自 1999 年以来&#xff0c;Wigderson 一直担…

Python五子棋VS人机对战

上一次编写了一个python五子棋游戏,但是属于玩家之间的对战。今天介绍五子棋和人机对战。本博文目的是教学和一些毕业设计。 目前电脑下棋逻辑算法还是比较简单的,不能和市面上五子棋相提并论,请大家理想对待! 代码: import pygame import sys import tkinter as tk fro…

再拓信创版图-Smartbi Insight V11与东方国信CirroData数据库完成兼容适配认证

近日&#xff0c;思迈特商业智能与数据分析软件 [简称&#xff1a;Smartbi Insight] V11与北京东方国信科技股份有限公司 &#xff08;以下简称东方国信&#xff09;CirroData-OLAP分布式数据库V2.14.1完成兼容性测试。经双方严格测试&#xff0c;两款产品能够达到通用兼容性要…

python语言零基础入门——注释、print()函数、input()函数

目录 一、注释 1.块注释 2.行内注释 3.多行注释 二、打印变量 1.print()函数&#xff1a;输出/打印指定内容 2.input()函数&#xff1a;输入指定内容 三、编程题&#xff1a;个人名片 一、注释 1.块注释 以#开始&#xff0c;直到本行结束都是注释为了保证代码的可读性…

初步学习node.js文件模块

环境已安装好&#xff1b; 写一个read1.js如下&#xff1b; var fs require("fs"); var data ;// 创建一个流 var stream1 fs.createReadStream(test1.jsp); stream1.setEncoding(UTF8);// 绑定data事件 stream1.on(data, function(mydata) {data mydata; });/…

Unity ECS

一&#xff1a;前言 ECS与OOP不同&#xff0c;ECS是组合编程&#xff0c;而OOP的理念是继承 E表示Entity&#xff0c;每个Entity都是一个有唯一id的实体。C表示Component&#xff0c;内部只有属性&#xff0c;例如位置、速度、生命值等。S表示System&#xff0c;驱动实体的行为…

Leetcode. 12 整数转罗马数字

罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符 数值 I 1 V 5 X 10 L 50 C 100 D 500 M 1000 例…

原来我一直被骗了!Burp suite诱导劫持攻击【附工具】

一、点击劫持 点击劫持是一种基于界面的攻击&#xff0c;用户通过点击诱饵网站中的一些其他内容被诱骗点击隐藏网站上的可操作内容。举例来说&#xff0c;一个网络用户可能会访问一个诱饵网站&#xff08;可能是通过电子邮件提供的链接&#xff09;&#xff0c;并点击一个按钮以…

C语言---贪吃蛇(二)---逻辑和代码的实现

文章目录 前言1.准备工作2.蛇的相关属性3.游戏流程设计3.1.游戏开始(GameStart)3.1.1.设置光标位置3.1.2.隐藏光标3.1.3.打印欢迎界面3.1.4.创建地图3.1.5.初始化蛇身3.1.6.创建食物 3.2.游戏运行(GameRun)3.2.1.打印信息栏3.2.2.蛇身的移动3.2.2.1.判断下一个结点是否为食物3.…

【Linux】iptables的应用

iptables 防火墙 防火墙是一种网络安全系统&#xff0c;它位于内部网络与外部网络&#xff08;如互联网&#xff09;之间&#xff0c;通过实施预定义的安全策略来控制网络间的通信。防火墙的主要目标是保护内部网络资源免受未经授权的访问、攻击或潜在威胁&#xff0c;同时允…

FFmpeg源码编译

msys2 依赖环境安装 依赖环境安装编译X264编译 fdk-aac文件处理编译x265编译FFmpeg 依赖环境安装 编译X264 用于h264 AVC视频格式编码 CCcl ./configure --enable-shared #指定使用cl,编译成动态链接库 make -j32 #使用32线程进行编码 make install命令一 关于第一条命令执…

VUE的import store from ‘./vuex/store改为‘ import store from ‘./vuex/store.js‘

ERROR Failed to compile with 1 error 下午5:25:40 error in (webpack)-dev-server/client?http://10.18.173.180:8081/sockjs-node Syntax Error: no such file or directory, open D:\4myroom\H…

2024年,新手做抖店千万犯这几点错误,轻则保证金,重则封店!

哈喽~我是电商月月 很多做抖音小店的新手朋友都忽略了违规操作这一部分&#xff0c;交完保证金以为后续不开了保证金还能退回&#xff1f;别天真了&#xff01; 不了解抖音小店的行为规则&#xff0c;违规了不仅保证金没了&#xff0c;严重的话&#xff0c;店铺都开不下去&am…

【精简改造版】大型多人在线游戏BrowserQuest服务器Golang框架解析(2)——服务端架构

1.架构选型 B/S架构&#xff1a;支持PC、平板、手机等多个平台 2.技术选型 &#xff08;1&#xff09;客户端web技术&#xff1a; HTML5 Canvas&#xff1a;支持基于2D平铺的图形引擎 Web workers&#xff1a;允许在不减慢主页UI的情况下初始化大型世界地图。 localStorag…

谷雨,春天的最后一次回眸

人生并不像火车要通过每个站似的经过每一个生活阶段。 今日谷雨&#xff0c;这不是技术文&#xff0c;是码哥的碎碎念 谷雨猕漫着芭蕉的味道动了心成了情白素贞的姻以伞结缘可天若无雨地上无伞断桥未断过客&#xff0c;能留下一段传奇吗&#xff1f;或许难难 倘若在江城边不是西…

盲人购物指南:智能化辅助引领超市购物新体验

作为一名资深记者&#xff0c;我有幸见证了一位盲人朋友借助一款名为蝙蝠避障的高科技辅助应用&#xff0c;独立完成超市购物之旅&#xff0c;这一过程充分展示了盲人购物指南新时代的到来。 在前往超市的路上&#xff0c;这款应用犹如一位贴心的“电子向导”&#xff0c;实时为…

编程范式之函数编程

文章目录 **核心概念****特征****优点****示例语言**案例 函数编程&#xff08;Functional Programming, FP&#xff09;是一种编程范式&#xff0c;它强调程序由一系列不可变的值和纯函数&#xff08;Pure Function&#xff09;组成&#xff0c;尽量避免副作用&#xff08;Sid…

Zynq7000系列中PL时钟使用

可编程逻辑&#xff08;PL&#xff09;具有自己的时钟管理生成和分配功能&#xff0c;并从处理器系统&#xff08;PS&#xff09;中的时钟发生器接收四个时钟信号&#xff08;如图25-10所示&#xff09;。 在嵌入式系统中&#xff0c;PL时钟的管理和分配对于确保逻辑电路的正确…

微波炉定时器开关

微波炉火力调节开关及定时器开关内部结构 参考链接&#xff1a; 微波炉火力调节开关及定时器开关判断好坏小经验-百度经验 (baidu.com)https://jingyan.baidu.com/article/5d6edee2d175c399eadeecfd.html微波炉拆解图示&#xff0c;微波炉结构原理&#xff0c;轻松玩转微波炉维…

使用eNSP配置OSPF多区域实验

一、实验拓扑 二、实验要求 1、R4为ISP&#xff0c;其上只配置IP地址&#xff1b;R4与其他所直连设备间均使用公有IP&#xff1b; 2、R3-R5、R6、R7为MGRE环境&#xff0c;R3为中心站点&#xff1b; 3、整个OSPF环境IP基于172.16.0.0/16划分&#xff1b;除了R12有两个环回&…
最新文章