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

linux中利用fork复制进程,printf隐藏的缓冲区,写时拷贝技术,进程的逻辑地址与物理地址

1.prinf隐藏的缓冲区

1.思考:为什么会有缓冲区的存在?

2.演示及思考?

1).演示缓存区没有存在感
那为什么我们感觉不到缓冲区的存在呢?我们要打印东西直接就打印了呢?
我们用代码演示一下:

比如打开一个main.c,输入内容如下:

 #include <stdio.h>int main(){printf("hello");}

我们运行的之后直接就打印了hello,好像没有感觉到缓冲区 的存在;
原因是因为此时程序已经结束了,它会刷新缓冲区的内容;

2)演示缓冲区的存在

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(){printf("hello");sleep(3);exit(0);
}

3.强制刷新
(1)方法一:遇到\n自动刷新
printf("hello\n");
(2)使用fflush刷新屏幕
fflush(stdout);

  1. _exit与exit

exit是先刷新缓冲区,然后再调用_exit(真正的退出);
_exit直接退出,不会刷新缓冲区;

比如如下的代码:

 #include <stdio.h>#include <stdlib.h>#include <unistd.h>int main(){printf("hello");//fflush(stdout);sleep(3);_exit(0);//注意这里,不输出hello}

5.总结
printf将内容先写入到缓冲区中,缓冲区刷新到界面(屏幕)上的条件是:
(1)缓冲区放满
(2)缓冲区未满,强制刷新缓冲区到屏幕(方法一:\n;方法二:主动刷新:fflush(stdout));
(3)程序结束时,自动刷新缓冲区:exit方法;

6.为什么会有缓冲区的存在?

屏幕是一个硬件设备,是由操作系统来管理的,因此printf打印的时候需要调用操作系统的接口才能完成,这个时候我们需要从用户态切换到内核态,这个开销是比较大的.

2.fork复制进程  (重点)

1)shell:

在计算机科学中,Shell俗称壳(用来区别于核),是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)。它类似于DOS下的COMMAND.COM和后来的cmd.exe。它接收用户命令,然后调用相应的应用程序。

我们就是通过命令解释器(称为shell)(bash是命令解释器中的一种)和内核和系统进行交互的(Windows通过图形界面进行交互的);例如我们把ls交给bash,bash帮我们运行ls,然后把结果给用户;

2)fork如何复制进程?

fork是把已有的进程复制一份,当然把PCB也复制了一份,然后申请一个PID,子进程的PID=父进程的PID+1;

   如果父子进程想要做不同的事情,那么我们通过返回值来判断;
man fork

代码如下(代码下去自己练习,理解):

#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <stdlib.h>int main()
{char *s=NULL;int n=0;//控制父子进程执行的次数;pid_t id=fork();assert(id!=-1);if(id==0)//子进程{s="child";n=3;}else//父进程{s="parent";n=7;}//父子进程int i=0;for(;i<n;i++){printf("s=%s\n",s);sleep(1);}exit(0);
}

父子进程是两个独立的进程,各自执行各自的代码;如果父子进程要做不一样的事情,就通过if  else返回值来操作;

3)fork的时机

fork产生的这个子进程不是从头开始执行的,而是从fork之后开始执行的,就是说fork下面的代码子进程才开始执行,具体的是说从返回值这里子进程开始执行,子进程不会再fork了,所以不会出现子进程再去fork产生一个子进程的问题.
也就是说:从返回值这里开始,父进程返回子进程的PID,子进程返回0;

4)getppid与getpid

getppid:得到一个进程的父进程的PID;
getpid:得到当前进程的PID;

man getpid;
man getppid

3.fork补充:

操作系统精髓与设计原理第101页;

4.如何学好多进程以及面试考点?

1)充分理解多进程的概念(每次程序多执行几次,多理解一下)

2)考点:

fork多以笔试的形式出现;

面试的考点:

例如:

1.我们在进程中看到的地址是进程的物理地址还是逻辑地址?(为什么这么问,单进程不分物理地址和逻辑地址吗);

2.进程同步设计(比如多进程抢夺资源)(难点,用程序实现)

3.fork与文件指针

(1)fork 以后,父进程打开的文件指针位置在子进程里面是否一样?(先open再fork)
(2)能否用代码简单的验证一下?
(3)先fork再打开文件父子进程是否共享偏移量?父进程打开的文件指针位置在子进程里面是否一样?能否用代码简单验证一下.(先fork再open会怎么样?)

4.fork+exec

5.僵死进程原因及处理方法;

5.内存管理相关概念

1.简单分页 逻辑页 物理页 页表的概念:
从哲学层次看操作系统157页(需要详细看)

2.虚拟内存:

虚拟内存提供的三个重要的能力:
1) 它将主存看成是一个存储在磁盘上的地址空间的高速缓存,在主存中只保存活动区域,根据需要在磁盘和主存之间来回传送数据,使得能够运行比内存大的多的进程。
2) 它为每个进程提供了一致的地址空间,从而简化了存储器管理.
3) 它保护每个进程的地址空间不被其他进程破坏 .

6.写时拷贝技术

不采用写时拷贝,如何fork?

第一:复制开销比较大;
第二:占用内存空间;
所以我们对fork复制进程的过程就做了一个优化-----写时拷贝技术;

综上,就是fork的时候,子进程直接把父进程的页表复制过来,子进程发生写入(修改)的时候才分配内存复制,然后进行相应的页表修改.

写时拷贝是一种可以推迟甚至免除拷贝数据的技术.

内核设计与实现22页;

7.我们在进程中看到的地址是进程的物理地址还是逻辑地址?

我们先来看代码: (打印n的地址)

 printf("s=%s,pid=%d,ppid=%d,n的地址为:%p\n",s,getpid(),getppid(),&n);//打印n的地址

 

8.进程的逻辑地址与物理地址

父子进程中n的值都不一样,那么我们为什么看到n的地址是相同的呢?

我们在进程中看到的地址就是进程的逻辑地址(进程的4G空间,从0开始,一直往上增长);

32位系统上,都有一个0-4G的地址空间:
在Linux系统上,最上面这1G由内核使用,下面3G是用户在使用;
为什么是4G呢?在32位系统上,能够寻址的范围就是2^32=4294967296字节/1000=4294976K /1000=4294M /1000=4.29 G 约等于4G  .

而我们把所有的地址都编号,

1K=2^10 ,4K=2^12
物理页面能有多少个页面呢?4G/4K=2^32 / 212=2(32-12)=2^20个页面

所以说,父子进程逻辑地址一样,但是物理地址是不一样的;

以前我们的程序都是只有一个进程,我们逻辑地址相同,那么我们的逻辑地址映射过去的物理地址肯定也是相同的一块空间,只有一个进程,就不用刻意去理解逻辑地址和物理地址的差异;对于同一进程,逻辑地址相同,物理地址肯定相同.
现在,我们的程序都是多进程的,逻辑地址相同,对应的物理地址就不一定相同了;也就是说A进程和B进程的逻辑地址相同,就不能说明物理地址一定相同,我们还需要看各自的页表,看看页表是否相同.(页表就是逻辑页和物理页的映射关系);
不同进程的逻辑地址是没有比较的意义的;

9.为什么在程序中不直接使用物理地址呢?

我们无法预知哪些物理地址是空闲的,同时空闲的也是动态变化的,程序在不断的申请释放空间中.

相关文章:

linux中利用fork复制进程,printf隐藏的缓冲区,写时拷贝技术,进程的逻辑地址与物理地址

1.prinf隐藏的缓冲区 1.思考:为什么会有缓冲区的存在? 2.演示及思考? 1).演示缓存区没有存在感 那为什么我们感觉不到缓冲区的存在呢?我们要打印东西直接就打印了呢? 我们用代码演示一下: 比如打开一个main.c,输入内容如下: #include <stdio.h>int main(){printf…...

java游戏制作-拼图游戏

一.制作主界面 首先创建一个Java项目命名为puzzlegame 结果&#xff1a;】 二.设置界面 代码&#xff1a; 三.初始化界面 代码&#xff1a; 优化代码&#xff1a; 四.添加图片 先在Java项目中创建图片文件夹&#xff0c;将图片导入其中 管理图片&#xff1a; 五.打乱图片顺序...

使用sklearn报AttributeError: ‘NoneType‘ object has no attribute ‘split‘

错误原因 在使用scikit-learn的时候报AttributeError: NoneType object has no attribute split Exception ignored on calling ctypes callback function: <function _ThreadpoolInfo._find_modules_with_dl_iterate_phdr..match_module_callback at 0x7fb757978160> T…...

C++学习 --map

目录 1&#xff0c; 什么是map 2&#xff0c; 创建map 2-1&#xff0c; 标准数据类型 2-2&#xff0c; 自定义数据类型 2-3&#xff0c; 其他创建方式 3&#xff0c; 操作map 3-1&#xff0c; 赋值 3-2&#xff0c; 插入元素(insert) 3-2-1&#xff0c; 插入标准数据类…...

基于Qt QList和QMap容器类示例

## QList<T> QList<T>容器是一个数组列表,特点如下: 1.大多数情况下可以用QList。像prepend()、append()和insert()这种操作,通常QList比QVector快的多。这是因为QList是基于index标签存储它的元素项在内存中(虽然内存不连续,这点与STL的list 是一样的),比…...

Flask学习一:概述

搭建项目 安装框架 pip install Flask第一个程序 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return "Hello World"if __name__ __main__:app.run()怎么说呢&#xff0c;感觉还不错的样子。 调试模式 if __name__ __main__:a…...

LeetCode:689. 三个无重叠子数组的最大和(dp C++)

目录 689. 三个无重叠子数组的最大和 题目描述&#xff1a; 实现代码与解析&#xff1a; dp 原理思路&#xff1a; 滑动窗口&#xff1a; 原理思路&#xff1a; 689. 三个无重叠子数组的最大和 题目描述&#xff1a; 给你一个整数数组 nums 和一个整数 k &#xff0c;找…...

Leetcode—206.反转链表【简单】

2023每日刷题&#xff08;三十三&#xff09; Leetcode—206.反转链表 头插法实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ struct ListNode* reverseList(struct ListNode* head) {if(head NULL…...

Linux - 内存 - 预留内存占用分析

说明 Linux启动log中会显示平台的内存信息&#xff0c;公司SOC平台&#xff0c;物理DRAM实际size是128M&#xff0c;但是启动log中total size不足128MB&#xff0c;并且预留内存&#xff08;82272K reserved&#xff09;过多&#xff0c;启动log如下&#xff1a; Memory: 480…...

Java学习之路 —— Java高级

文章目录 前言1. 单元测试2. 反射2.1 获取Class对象的三种方式2.2 获取类的构造器的方法2.3 获取类的成员变量2.4 获取类的成员方法2.5 反射的作用 3. 注解3.1 自定义注解3.2 注解的原理3.3 元注解3.4 注解的解析 4. 动态代理5. 总结 前言 终于走到新手村的末端了&#xff0c;…...

git使用及常用命令

在初入公司中&#xff0c;若使用的是git管理工具&#xff0c;需要做以下步骤&#xff1a; 1&#xff0c;常用命令在&#xff1a; &#xff08;1&#xff09;&#xff0c;git config --global user.name xxx(名字) //若不设置 那么下次提交代码时会报错 其次该设置名字和…...

vue 学习 -- day36(分析工程结构)

//引入的不再是Vue构造函数了&#xff0c;引入的是一个名为createApp的工厂函数 import { createApp } from vue import App from ./App.vue //创建应用实例对象——app(类似于之前Vue2中的vm&#xff0c;但app比vm更“轻”&#xff0c;它少了很多属性和方法) const app creat…...

SQL Injection

SQL Injection SQL injection&#xff08;SQL注入&#xff09;&#xff0c;通过在输入字段或URL查询参数中执行SQL命令&#xff0c;导致对数据库的未经授权的访问。如果SQL注入成功&#xff0c;未经授权的人可能会读取、创建、更新甚至删除数据库表的记录 举个例子&#xff1a;…...

【Go入门】 Go搭建一个Web服务器

【Go入门】 Go搭建一个Web服务器 前面小节已经介绍了Web是基于http协议的一个服务&#xff0c;Go语言里面提供了一个完善的net/http包&#xff0c;通过http包可以很方便的搭建起来一个可以运行的Web服务。同时使用这个包能很简单地对Web的路由&#xff0c;静态文件&#xff0c…...

VS 将 localhost访问改为ip访问

项目场景&#xff1a; 使用vs进行本地调试时需要多人访问界面,使用ip访问报错 问题描述 vs通过ip访问报错 虚拟机或其它电脑不能正常打开 原因分析&#xff1a; 原因是vs访问规则默认是iis,固定默认启动地址是localhost 解决方案&#xff1a; 1.vs项目启动之后会出现这个 右…...

app使用

font-face{font-family:‘kaishu’; src: url(data:application/font-ttf;charsetutf-8;base64,AAEAAAASAQAABAAgRFNJR5PpVzIAAAEsAAAacEdTVUIzhvftAAAbnAAAAXBPUy8yY8pHoQAAHQwAAABWY21hcAsTB9YAAB1kAADD5GN2dCAvAiIAADhSAAAA5pmcGdt/siFHQAA5OQAAAOiZ2FzcAAXAAkAAOiIAAAAEGds…...

【迅搜01】安装运行并测试XunSearch

安装运行并测试XunSearch 这回的新系列&#xff0c;我们将学习到的是一个搜索引擎 迅搜 XunSearch 的使用。这个搜索引擎在 PHP 圈可能还是有一点名气的&#xff0c;而且也是一直在更新的&#xff0c;虽说现在 ElasticSearch 已经是实际上的搜索引擎霸主了&#xff0c;而且还有…...

Mac电脑VSCode配置PHP开发环境

1.安装 PHP 首先&#xff0c;打开终端&#xff0c;安装 Homebrew&#xff0c;输入如下命令&#xff1a; $ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装了 Homebrew 之后&#xff0c;你可以使用下面的…...

SpirngBoot + Vue 前后端分离开发工具代码

✅作者简介&#xff1a;大家好&#xff0c;我是Leo&#xff0c;热爱Java后端开发者&#xff0c;一个想要与大家共同进步的男人&#x1f609;&#x1f609; &#x1f34e;个人主页&#xff1a;Leo的博客 &#x1f49e;当前专栏&#xff1a; Java从入门到精通 ✨特色专栏&#xf…...

【数据结构初阶】单链表(附全部码源)

单链表 1&#xff0c;单链表的概念及结构2&#xff0c;单链表的实现2.1初始化内容&#xff08;所需文件&#xff0c;接口&#xff09;2.2申请结点2.3打印单链表2.4尾插2.5头插2.6尾删2.7头删2.8查找2.9在pos位置之后插入2.10在pos位置前面插入2.11删除pos之后的值2.12删除pos位…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Objective-C常用命名规范总结

【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名&#xff08;Class Name)2.协议名&#xff08;Protocol Name)3.方法名&#xff08;Method Name)4.属性名&#xff08;Property Name&#xff09;5.局部变量/实例变量&#xff08;Local / Instance Variables&…...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...