进程复制fork详解 僵尸进程 孤儿进程 写时拷贝技术 缓冲区

news2024/11/17 13:52:59

fork函数讲解

  • 进程复制
    • fork基本使用
    • 简单分页 逻辑页 物理页 页表
    • fork的三个面试练习题
    • 缓冲区
    • 僵死进程
    • 孤儿进程
    • 写时拷贝
  • 进程替换
    • exexc 介绍
    • 简易命令解释器
      • strtok()函数讲解

进程复制

fork基本使用

在这里插入图片描述

父进程fork后,新的进程产生,新的进程就继续从fork往后的程序往下执行,新的进程不会继续执行fork,父进程中fork复制了该进程,然后fork的返回值是子进程的pid ,子进程中fork的返回值被强制为0,所以可以通过fork的返回值来判断

#include<stdio.h>
#include<unistd.h>
int main(){
	int n=0;
	char*s=NULL;
	pid_t id=fork();
	if(id==-1){
		printf("fork error\n");
		exit(1);
	}

	if(id==0){
		n=3;
		s="child";
	}
	else{
		n=7;
		s="parent";
	}
	for(int i=0;i<n;i++){
		printf("s=%s,pid=%d\n",s,getpid());
		sleep(1);
	}
	exit(0);
}   
            

在这里插入图片描述

for(int i=0;i<n;i++){
	printf("s=%s,pid=%d,ppid=%d,n=%d,&n=%p\n",s,getpid(),getppid(),n,&n);
	sleep(1);
}

在这里插入图片描述
解释一下,为啥在父进程和子进程中n的地址是相同的:fork一份产生子进程,n的位置,即距离起始位置的偏移量恰好和父进程相同,在父进程中n的那块空间存储7,子进程中那块空间存储3,两者互不影响。6

简单分页 逻辑页 物理页 页表

4K为一个页面
程序中看到的都是逻辑地址,实际上是偏移量,调试看到的都是逻辑地址,我们不知道物理地址,每次是映射到物理地址,一般是查表
在这里插入图片描述
内核用1G,

在这里插入图片描述

fork的三个面试练习题

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
int main(){
	fork()||fork();
	printf( "1\n");
}

第一个fork执行后,赋值一个进程,在第一个进程中,fork返回值大于0,在或||表达式中,第一个为真,后面就不执行了,直接返回真,子进程中,第一个fork返回值为0,在或||表达式中,第一个为假,后面继续执行,执行fork,这里没有写if语句,往后面执行就行,最终打印111
在这里插入图片描述
在这里插入图片描述

 int main()
 {
	for(int i = 0 ; i < 2; i++ )
	{
		fork();
		printf("a\n");
	}
	exit(0);
}

结果为aaaaaa
在这里插入图片描述
这个和上面的一个区别就是少了一个\n ,

 int main()
 {
	for(int i = 0 ; i < 2; i++ )
	{
		fork();
		printf("a");
	}
	exit(0);
}

缓冲区

缓冲区(可以想象成一个字符数组),使程序的开销变小,缓冲区满足三个条件,可以提交
1缓冲区满了,
2或者用户强制刷新(用’\n’),
3程序结束

exit(0);退出进程,
1刷缓冲区,2调用_exit(0)退出进程

fflush(stdout);//stdin stdout stderr
该函数可以和\n达到同样的效果,\n可以刷新屏幕,但是文件不行,文件刷新就只能用fflush(stdout)

fork复制进程的时候,连缓冲区也要复制一份,所以a是8个
在这里插入图片描述

僵死进程

子进程先结束,但是父进程没有调用wait获取子进程的退出码,会导致子进程的进程控制块结构体一直在占用id
处理僵死进程
调用wait,把父进程阻塞住了,得到子进程的退出码为3
让父进程死掉,变成孤儿进程,让其他进程接管子进程,

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<stirng.h>
#include<sys/wait.h>
int main(){
	int n=0;
	char*s=NULL;
	pid_t id=fork();
	if(id==-1){
		printf("fork error\n");
		exit(1);
	}

	if(id==0){
		n=3;
		s="child";
	}
	else{
		n=7;
		s="parent";
		int val=0;
		pid_t child_pid=wait(&val);
		//printf("child_pid=%d,val=%d\n",child_pid,val>>8);
		if(WIFEXITED(val)){//是否正常结束
			printf("child_pid=%d,val=%d\n",child_pid,WEXITSTATUS(val));//去除退出码
	}
	for(int i=0;i<n;i++){
		printf("s=%s,pid=%d\n",s,getpid());
		sleep(1);
	}
	exit(3);
}   

孤儿进程

子进程的父进程结束,该进程就变成了孤儿进程,系统会在给该进程找一个父进程,会自动获取该子进程的退出码

写时拷贝

fork时,先不着急复制,先共享,等到需要修改该页面数据的时候,再复制该页面一份,延迟拷贝

进程替换

exexc 介绍

每一个新的进程产生都是,先复制,再替换
把当前进程替换成另一个进程

没有返回值,替换成功,如果有返回值,说明替换失败,

int execl(const char* path, const char * arg,(char*)0...);

*path:新替换的程序的路径名称
*arg :传给新程序主函数的第一个参数,一般为程序的名字
*arg 后面是剩余参数列表,参数个数可变,必须以空指针作为最后一个参数

int execlp(const char* file, const char * arg,...);

会在bin路径下寻找,能找到就能启动,找不到就失败

简易命令解释器

strtok()函数讲解

char*strtok(char*str,const char*delim);

str是原本的字符串,这里不能是常量,因为会修改,实现机理是将每个分隔符换成’\0’,返回每个字符串的首地址,delim是分隔符,是个常量
strtok里面有个静态偏移量指针,第二次调用时,将NULL传入,就可以通过静态偏移量指针找到目前的位置,继续分隔,当到末尾时,s就返回为空

获取用户的id,返回值为0就是管理员

uid_t getuid(void)

通过uid我们可以获取用户的很多详细信息,都在passwd的结构体里面,

struct passwd*ptr=getpwuid(uid);

用ptr指向这个结构体,可以访问结构体所有的属性,

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

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

相关文章

Spring集成Web

目录 1、简介 2、监听器 3、Spring提供的listener 3.1、xml 3.2、配置类 3.3、WebApplicationContextUtils 3.4、说明 4、自己复现的listener 4.1、ContextLoaderListener 4.2、WebApplicationContextUtils 4.3、Web调用 ⭐作者介绍&#xff1a;大二本科网络工程专业…

Less is More: Focus Attention for Efficient DETR

摘要 类似detr的模型显著提高了探测器的性能&#xff0c;甚至优于经典的卷积模型。然而&#xff0c;在传统的编码器结构中&#xff0c;所有的标记都带来了冗余的计算负担。最近的稀疏化策略利用了信息标记的一个子集&#xff0c;通过稀疏编码器来降低注意力的复杂性&#xff0…

观测,让运维更简单!龙蜥社区系统运维 MeetUp 等你报名

为了让广大社区用户和开发者近距离感受 Linux 和 eBPF 技术的魅力&#xff0c;龙蜥社区系统运维于 08 月 12 日在杭州举行 MeetUp 。过去&#xff0c;系统运维 SIG 和大家一起交流了 eBPF 在安全和网络的最佳应用和实践&#xff0c;以及 Linux 在手机和服务器上的运维经验等技术…

深度学习训练营之CGAN生成手势图像

深度学习训练营之CGAN生成手势 原文链接CGAN简单介绍环境介绍前置工作数据导入所需的包加载数据创建数据集查看数据集 模型设置初始化模型的权重定义生成器构造判别器 模型训练定义损失函数设置超参数正式开始训练 结果可视化 原文链接 &#x1f368; 本文为&#x1f517;365天…

leetcode 763. 划分字母区间

2023.8.3 本题的关键是要确保同一字母需要在同一片段中&#xff0c;而这就需要关注到每个字母最后一次出现的位置。 思路&#xff1a;用一个哈希表保存每个字母&#xff08;26个&#xff09;最后一次出现的位置。然后从头遍历&#xff0c;不断更新最右边界&#xff0c;直到当前…

LLVM笔记1

参考&#xff1a;https://www.bilibili.com/video/BV1D84y1y73v/?share_sourcecopy_web&vd_sourcefc187607fc6ec6bbd2c74a3d0d7484cf 文章目录 零、入门名词解释1. Compiler & Interpreter2. AOT静态编译和JIT动态解释的编译方式3. Pass4. Intermediate Representatio…

Eureka增加账号密码认证登录

一、业务背景 注册中心Eureka在微服务开发中经常使用到&#xff0c;用来管理发布的微服务&#xff0c;供前端或者外部调用。但是如果放到生产环境&#xff0c;我们直接通过URL访问的话&#xff0c;这显然是不安全的。 所以需要给注册中心加上登录认证。 通过账号和密码认证进行…

openGauss学习笔记-30 openGauss 高级数据管理-别名

文章目录 openGauss学习笔记-30 openGauss 高级数据管理-别名30.1 语法格式30.1.1 列别名语法30.1.2 表别名语法 30.2 参数说明30.3 示例 openGauss学习笔记-30 openGauss 高级数据管理-别名 SQL可以重命名一张表或者一个字段的名称&#xff0c;这个名称为该表或该字段的别名。…

Spring:JDBCTemplate

JDBCTemplate 概述 概述 JDBC&#xff08;Java DataBase Connectivity&#xff0c;Java 数据库连接&#xff09;&#xff0c; 一 种用于执行 SQL 语句的 Java API&#xff08;Application Programming Interface &#xff0c; 应用程序设计接口 &#xff09;&#xff0c;可以为…

【每日一题】—— C. Mocha and Hiking(Codeforces Round 738 (Div. 2))

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;每日一题 &#x1f48c;其他专栏&#xff1a; &#x1f534; 每日反刍 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓称…

IO流【笔记】

1. IO概述 1.1 什么是IO 生活中&#xff0c;你肯定经历过这样的场景。当你编辑一个文本文件&#xff0c;忘记了ctrls &#xff0c;可能文件就白白编辑了。当你电脑上插入一个U盘&#xff0c;可以把一个视频&#xff0c;拷贝到你的电脑硬盘里。那么数据都是在哪些设备上的呢&a…

软件开发过程中前后端联调相关问题

一、接口调用三步曲 1. uniapp接口调用 data中定义 onload中调用 例如&#xff1a;this.getSwiperList()//调用获取轮播图数据的方法 method中定义获取方法 2. 微信小程序接口调用 reques.js中接口封装 如&#xff1a;ScenicspotInfo &#xff08;data&#xff09;> re…

高级web前端开发工程师的岗位职责最新(合集)

高级web前端开发工程师的岗位职责最新1 职责&#xff1a; 1.主导公司前端开发的技术方向&#xff0c;指导其他前端开发人员工作 2.负责产品的Web前端开发及用户交互体验设计; 3.基于HTML、CSS、JavaScript标准进行页面制作&#xff0c;编写界面组件; 4.协同后台开发工程师&…

8.4 day05软件学习

文章目录 微服务的概念微服务的原则微服务的特征&#xff1a;集群介绍 spring aop 在家学习效率真不高&#xff0c;下午好兄弟喊出去玩&#xff0c;一直到晚上才回来&#xff0c;赶紧总结一下早上学习的内容。 继续看java基础进阶的思想&#xff0c;之前学的很多都忘了。 微服…

网工内推 | 实施、售后工程师,厂商认证优先

01 安井食品集团股份有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1.负责集团组网的网络规划、实施、维护工作&#xff1b; 2.负责公司局域网的网络规划、实施、维护工作&#xff1b; 3.负责公司企业安全系统规划、实施、维护工作&#xff1b; 4、负责公…

百度UEditor编辑器如何关闭抓取远程图片功能

百度UEditor编辑器如何关闭抓取远程图片功能 这个坑娘的功能&#xff0c;开始时居然不知道如何触发&#xff0c;以为有个按钮&#xff0c;点击一下触发&#xff0c;翻阅了文档&#xff0c;没有发现&#xff0c;然后再网络上看到原来是复制粘贴非白名单内的图片到编辑框时触发&a…

LT6711A 是一款HDMI 2.0转DP 1.2/EDP 1.4的芯片,实用于AR或者PC以及PAD

LT6711A 1.概述&#xff1a; Lontium LT6711A是HDMI2.0到DP1.2转换器&#xff0c;内部有c型替代模式开关和PD控制器。对于HDMI输入&#xff0c;LT6711A具有一个HDMI2.0接收器&#xff0c;有1个时钟通道和3个数据通道&#xff0c;每个数据通道最大运行6Gb/s&#xff0c;最大输…

DAY02_Spring第三方资源配置管理Spring容器Spring注解开发Spring整合Mybatis和Junit

目录 一 第三方资源配置管理1 管理DataSource连接池对象问题导入1.1 管理Druid连接池1.2 管理c3p0连接池 2 加载properties属性文件问题导入2.1 基本用法2.2 配置不加载系统属性2.3 加载properties文件写法 二 Spring容器1 Spring核心容器介绍问题导入1.1 创建容器1.2 获取bean…

智能汽车驾驶演进:虚拟ECU种类与优劣分析

现代汽车更安全、更舒适、更智能的代价是车载ECU&#xff08;Electronic Control Unit&#xff09;数量的迅速增长&#xff0c;与之相对应的是ECU上规模软件越来越大、软件开发成本在整车制造成本中的占比越来越高。车企可以从规则与方法两个角度入手来解决上述问题&#xff1a…

ES6新增的语法

ES6实际上是一个泛指&#xff0c;泛指 ES2015 及后续的版本 1&#xff0c;let用于声明变量的关键字 let 声明的变量只在所处于的代码块内有效 if (true) { let a 10 } console.log(a) // a is not defined 2, let 不存在变量提升 console.log(a) // a is not deined let a 1…