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

缓冲区的用途 和 fork复制进程

printf隐藏的缓冲区

(1)为什么会有缓冲区?

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

运行之后 和平时似乎没什么区别。原因是因为此时程序已经结束了,会刷新缓冲区的内容;

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

这里可以发现 hello明显打印经过了时间的等待 之后才出现在屏幕上。

强制刷新

方法一:遇到\n自动刷新 printf("hello\n");

方法二:使用fflush刷新屏幕 fflush(stdout);

方法三:_exit与exit

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

_exit直接退出 不会刷新缓冲区;

总结

printf将内容先写入到缓冲区,缓冲区刷新到界面上的条件是:

(1)缓冲区放满

(2)缓冲区未满,强制刷新缓冲区到屏幕上(\n    或者   fflush(stdout))

(3)程序结束,自动刷新缓冲区:exit方法;

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

缓冲区的存在主要是为了减少用户态和内核态之间的频繁切换,从而提高系统的整体效率。

        数据暂存:缓冲区可以暂存从用户态传入的数据,当数据积累到一定程度后再一次性传递给内核态,这样可以减少切换次数。

        速度匹配:不同设备的数据传输速度可能不同,缓冲区可以协调这些速度差异,使得数据传输更加平稳和高效。

        错误处理:缓冲区还可以用于暂存错误信息,当发生错误时,系统可以更灵活地处理这些错误,而不是立即中断当前操作。

缓冲区通常由操作系统管理,操作系统会在内存中分配一块区域作为缓冲区。应用程序将数据写入缓冲区,操作系统负责将缓冲区中的数据传递给硬件设备。同样,从硬件设备读取的数据也会先存入缓冲区,然后由应用程序从缓冲区中读取。

fork复制进程

(1)shell

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

我们就是通过命令解释器(shell)(bash是命令解释器中的一种)和内核和系统进行交互的;

例如 在Linux中 我们输入ls命令 将ls交给bash,bash帮我们运行ls,然后再将运行出来的结果交给用户。bash作为用户和内核的一个媒介 进行命令解释

(2)fork是如何复制进程的?

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

        如果父子进程想要做不同的事情,那么就需要通过其返回值来判断

#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


http://www.xdnf.cn/news/7090.html

相关文章:

  • 深度解析:AWS NLB 与 ALB 在 EKS 集群中的最佳选择
  • 内容中台智能推荐系统构建与演进
  • Python 装饰器详解
  • 提示工程 - 系统提示(System Prompts)
  • AI日报 - 2025年05月19日
  • Fine-Tuning Llama2 with LoRA
  • STC89C52单片机模拟实现洗衣机控制 Proteus仿真
  • TYUT-企业级开发教程-第一章
  • Science Robotics 封面论文:基于形态学开放式参数化的仿人灵巧手设计用于具身操作
  • 如何完美安装GPU版本的torch、torchvision----解决torch安装慢 无法安装 需要翻墙安装 安装的是GPU版本但无法使用的GPU的错误
  • C++:⾯向对象的三⼤特性
  • Java正则表达式:从基础到高级应用全解析
  • ColorAid —— 一个面向设计师的色盲模拟工具开发记
  • 超越想象:利用MetaGPT打造高效的AI协作环境
  • Vue 3 中使用 md-editor-v3 的完整实例markdown文本
  • Pandas 构建并评价聚类模型② 第六章
  • 实现菜谱二级联动导航
  • ubuntu防火墙命令和放行ssh端口
  • 03 Nginx日志格式及可视化
  • Estimation(估算):业务分析师的“不确定性对抗术”
  • LeetCode Hot100刷题——除自身以外数组的乘积
  • 【设计模式】- 行为型模式2
  • 时序数据库、实时数据库与实时数仓:如何为实时数据场景选择最佳解决方案?
  • 【Linux】第十八章 调优系统性能
  • 结构体对齐三大法则
  • UART、SPI、IIC复习总结
  • 获取Class的方式有哪些?
  • 蓝桥杯19681 01背包
  • 医学影像开发的开源生态与技术实践:从DCMTK到DICOMweb的全面探索
  • NC61 两数之和【牛客网】