Linux 进程3-fork创建子进程继承父进程缓冲区验证

目录

1. fork创建子进程继承父进程缓冲区验证

1.1 write向标准输出(终端屏幕)写入数据验证

1.1.1 write函数写入数据不带行缓冲刷新 \n

1.1.2  write函数写入数据带行缓冲刷新 \n

1.2 fork创建前执行printf函数

1.2.1 fork创建前执行printf函数带\n,刷新缓冲区

1.2.2 fork创建前执行printf函数不带\n,缓冲区有缓冲数据

1.3 fork缓冲输出重定向

1.3.1 fork缓冲输出重定向到文件

1.3.2 fork缓冲输出重定向到文件,验证write无缓冲直接输出


1. fork创建子进程继承父进程缓冲区验证

1.1 write向标准输出(终端屏幕)写入数据验证

write函数为系统调用,无缓冲区,写入数据直接输出到终端

1.1.1 write函数写入数据不带行缓冲刷新 \n

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{printf("main 开始\n");int length = 0;char buf[] = "a write to stdout";//向标准输出(终端屏幕)写入buf数据//write函数为系统调用,无缓冲区,数据直接输出到终端。length = write(1, buf, strlen(buf));if(length != strlen(buf)){printf("write error\n");}return 0;
}

运行结果:

1.1.2  write函数写入数据带行缓冲刷新 \n

程序:

仅修改上述程序中的 : char buf[] = "a write to stdout\n";

运行结果:

1.2 fork创建前执行printf函数

1.2.1 fork创建前执行printf函数带\n,刷新缓冲区

printf函数带\n,刷新缓冲区,子进程继承父进程缓冲区里面无内容。

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{printf("main 开始\n");pid_t pid;int length = 0;char buf[] = "a write to stdout\n";//char buf[] = "a write to stdout";//向标准输出(终端屏幕)写入buf数据//write函数为系统调用,无缓冲区,直接输出到终端。length = write(1, buf, strlen(buf));if(length != strlen(buf)){printf("write error\n");}//验证不带 \n,子进程会继承,终端缓冲区内容。// printf 有\n 时,行缓冲区会刷新,刷新后缓冲区无内容。printf("fork 创建前:\n");pid=fork();if(pid<0){perror("fail to fork");}else if(pid==0){printf("在子进程中- \n");}else{sleep(1);//让子进程先执行完,在执行父进程printf("在父进程中- \n");}return 0;
}

运行结果:printf函数带\n,执行printf("fork 创建前:\n"); 刷新了缓冲区,子进程继承父进程缓冲区里面无内容。不会打印fork之前的printf内容。

1.2.2 fork创建前执行printf函数不带\n,缓冲区有缓冲数据

printf 无\n 时,行缓冲区不会刷新(除非行缓冲数据存满1024字节),缓冲区有缓冲数据。
下次刷新缓冲区时,缓冲区数据会输出。

程序:

仅修改上述程序的 printf("fork 创建前:"); 去掉printf函数的  \n

运行结果:由于执行 printf("fork 创建前:");,printf函数无 \n,缓冲区不会刷新,打印的内容:fork 创建前:,一直存在缓冲区中,没有输出。在fork 创建子进程时,父进程缓冲区数据被子进程继承,等到缓冲区刷新时,才会将 缓冲数据输出。

打印的数据 (main 开始,已不再缓冲区中 ; a write to stdout 无缓冲,已直接输出)。

fork 创建前:在子进程中-    //子进程程序运行,输出
fork 创建前:在父进程中-   //父进程程序运行,输出

1.3 fork缓冲输出重定向

重定向:将终端输出结果,重新定向到文件,缓冲区变为全缓冲。

fork缓冲输出重定向到文件,原来的行缓冲变为全缓冲,只有缓冲区满、人为调用刷新函数(fflush)、程序运行结束才会刷新。即使 printf函数带\n,也不会刷新缓冲区。

1.3.1 fork缓冲输出重定向到文件

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{//printf("main 开始\n");pid_t pid;int length = 0;char buf[] = "a write to stdout\n";//char buf[] = "a write to stdout";//向标准输出(终端屏幕)写入buf数据//write函数为系统调用,无缓冲区,直接输出到终端。length = write(1, buf, strlen(buf));if(length != strlen(buf)){printf("write error\n");}//验证不带 \n,子进程会继承,终端缓冲区内容。// printf 有\n 时,行缓冲区会刷新,刷新后缓冲区无内容。// printf 无\n 时,行缓冲区不会刷新(除非行缓冲数据存满1024字节),缓冲区有缓冲数据。//下次刷新缓冲区时,缓冲区数据会输出。printf("fork 创建前:\n");pid=fork();if(pid<0){perror("fail to fork");}else if(pid==0){printf("在子进程中- \n");}else{sleep(2);//让子进程先执行完,在执行父进程printf("在父进程中- \n");}return 0;
}

运行结果:

(1)终端运行结果

printf函数带\n,执行printf("fork 创建前:\n"); 刷新了缓冲区,子进程继承父进程缓冲区里面无内容。不会打印fork之前的printf内容。写入的的数据 ( a write to stdout 无缓冲,已直接输出)。

(2)执行./a.out > test.txt ,输出重定向到文件

fork缓冲输出重定向到文件,原来的行缓冲变为全缓冲只有缓冲区满、人为调用刷新函数(fflush)、程序运行结束才会刷新。即使 printf函数带\n,也不会刷新缓冲区。

运行结果:

写入的的数据 ( a write to stdout 无缓冲,直接输出)。

执行printf("fork 创建前:\n"); 原本会刷新了缓冲区,但重定向后,行缓冲变为全缓冲,\n不会刷新缓冲区。子进程继承了父进程缓冲区数据,子进程执行时,也会打印:fork 创建前:\n;

1.3.2 fork缓冲输出重定向到文件,验证write无缓冲直接输出

在main函数开始,加入 printf("main 开始\n");

程序:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>int main(int argc, char *argv[])
{printf("main 开始\n");pid_t pid;int length = 0;char buf[] = "a write to stdout\n";//char buf[] = "a write to stdout";//向标准输出(终端屏幕)写入buf数据//write函数为系统调用,无缓冲区,直接输出到终端。length = write(1, buf, strlen(buf));if(length != strlen(buf)){printf("write error\n");}//验证不带 \n,子进程会继承,终端缓冲区内容。// printf 有\n 时,行缓冲区会刷新,刷新后缓冲区无内容。// printf 无\n 时,行缓冲区不会刷新(除非行缓冲数据存满1024字节),缓冲区有缓冲数据。//下次刷新缓冲区时,缓冲区数据会输出。printf("fork 创建前:\n");pid=fork();if(pid<0){perror("fail to fork");}else if(pid==0){printf("在子进程中- \n");}else{sleep(2);//让子进程先执行完,在执行父进程printf("在父进程中- \n");}return 0;
}

运行结果:

(1)终端运行

printf("fork 创建前:\n"); 带有行缓冲刷新 \n ,子进程继承父进程缓冲区时,父进程缓冲区无数据,不会打印fork 创建前:

(2)执行./a.out > test.txt ,输出重定向到文件

函数运行时,从main函数开始:

①首先执行,printf("main 开始\n"); 但是,由于重定向后,行缓冲变为全缓冲,\n不会刷新缓冲区(只有缓冲区满、人为调用刷新函数(fflush)、程序运行结束才会刷新)。

子进程继承了父进程缓冲区数据,printf("main 开始\n");,子进程执行时,等待缓冲区刷新时,才会输出数据。

②执行写入函数 write(1, buf, strlen(buf));,写入数据,由于写入的的数据 ( a write to stdout 无缓冲,将会直接输出到终端)。

③执行printf("fork 创建前:\n"); 原本会刷新了缓冲区,但重定向后,行缓冲变为全缓冲,\n不会刷新缓冲区。

子进程继承了父进程缓冲区数据,printf("fork 创建前:\n"); ,子进程执行时,等待缓冲区刷新时,才会输出数据。

④子进程执行完,父进程执行,打印输出过程与子进程相同。

终端打印数据顺序分析:全缓冲,没有调用刷新函数,函数程序运行结束才会刷新缓冲区。

函数执行过程:

printf("main 开始\n");         //顺序2:子进程执行,数据存在缓冲区
write(1, buf, strlen(buf));         //顺序1:子进程执行时,最先输出到终端,无缓冲
printf("fork 创建前:\n");        //顺序3:子进程执行,数据存在缓冲区
printf("在子进程中- \n");        //顺序4:子进程执行,数据存在缓冲区

printf("main 开始\n");        /顺序5:父进程执行,数据存在缓冲区
printf("fork 创建前:\n");   /顺序6:父进程执行,数据存在缓冲区
printf("在父进程中- \n");     /顺序7:父进程执行,数据存在缓冲区

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Celery 全面指南:Python 分布式任务队列详解

Celery 全面指南&#xff1a;Python 分布式任务队列详解 Celery 是一个强大的分布式任务队列/异步任务队列系统&#xff0c;基于分布式消息传递&#xff0c;专注于实时处理&#xff0c;同时也支持任务调度。本文将全面介绍 Celery 的核心功能、应用场景&#xff0c;并通过丰富…

excel 列单元格合并(合并列相同行)

代码 首先自定义注解CellMerge&#xff0c;用于标记哪些属性需要合并&#xff0c;哪个是主键**&#xff08;这里做了一个优化&#xff0c;可以标记多个主键&#xff09;** import org.dromara.common.excel.core.CellMergeStrategy;import java.lang.annotation.*;/*** excel…

mac m4 Homebrew安装MySQL 8.0

1.使用Homebrew安装MySQL8 在终端中输入以下命令来安装MySQL8&#xff1a; brew install mysql8.0 安装完成后&#xff0c;您可以通过以下命令来验证MySQL是否已成功安装&#xff1a; 2.配置mysql环境变量 find / -name mysql 2>/dev/null #找到mysql的安装位置 cd /op…

Wi-SUN技术,强势赋能智慧城市构筑海量IoT网络节点

在智慧城市领域中&#xff0c;当一个智慧路灯项目因信号盲区而被迫增设数百个网关时&#xff0c;当一个传感器网络因入网设备数量爆增而导致系统通信失效时&#xff0c;当一个智慧交通系统因基站故障而导致交通瘫痪时&#xff0c;星型网络拓扑与蜂窝网络拓扑在构建广覆盖与高节…

FALL靶机攻略

1.下载靶机&#xff0c;导入靶机 下载地址&#xff1a;https://download.vulnhub.com/digitalworld/FALL.7z 开启靶机。 2. 靶机、kali设置NAT网卡模式 3. kali扫描NAT网卡段的主机 kali主机 nmap扫描&#xff1a;nmap 192.168.92.1/24 判断出靶机ip是192.168.92.133。开启…

蓝桥杯高频考点——二分(含C++源码)

二分 基本框架整数查找&#xff08;序列二分的模版题 建议先做&#xff09;满分代码及思路solution 子串简写满分代码及思路solution 1&#xff08;暴力 模拟双指针70分&#xff09;solution 2&#xff08;二分 AC&#xff09; 管道满分代码及思路样例解释与思路分析solution 最…

Rust vs. Go: 性能测试(2025)

本内容是对知名性能评测博主 Anton Putra Rust vs. Go (Golang): Performance 2025 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 再次对比 Rust 和 Go&#xff0c;但这次我们使用的是最具性能优势的 HTTP 服务器库---Hyper&#xff0c;它基于 Tokio 异步运…

【NUUO 摄像头】(弱口令登录漏洞)

漏洞简介&#xff1a;NUUO 是NUUO公司的一款小型网络硬盘录像机设备。 NUUO NVRMini2 3.0.8及之前版本中存在后门调试文件。远程攻击者可通过向后门文件handle_site_config.php发送特定的请求利用该漏洞执行任意命令。 1.Fofa搜索语句&#xff1a; 在Fofa网站&#xff0c;搜索&…

PyQt6实例_批量下载pdf工具_exe使用方法

目录 前置&#xff1a; 工具使用方法&#xff1a; step one 获取工具 step two 安装 step three 使用 step four 卸载 链接 前置&#xff1a; 1 批量下载pdf工具是基于博文 python_巨潮年报pdf下载-CSDN博客 &#xff0c;将这个需求创建成界面应用&#xff0c;达到可…

matlab 模拟 闪烁体探测器全能峰

clc;clear;close all %% 参数设置 num_events 1e5; % 模拟事件数 E 662e3; % γ射线能量&#xff08;eV&#xff09; Y 38000; % 光产额&#xff08;photon/MeV&#xff0c;NaI(Tl)&#xff09; eta 0.2; % 量子效率 G 1e6; …

启扬RK3568开发板已成功适配OpenHarmony4.0版本

启扬智能IAC-RK3568-Kit开发板支持Debian、Android等常见开源操作系统&#xff0c;目前已完成OpenHarmony4.0开源国产操作系统的适配工作&#xff0c;满足国产化开源操作系统客户的需求。 启扬智能IAC-RK3568-Kit开发板基于瑞芯微RK3568处理器设计&#xff0c;主频最高可达2.0G…

蓝桥与力扣刷题(蓝桥 山)

题目&#xff1a;这天小明正在学数数。 他突然发现有些止整数的形状像一挫 “山”, 比㓚 123565321、145541123565321、145541, 它 们左右对称 (回文) 且数位上的数字先单调不减, 后单调不增。 小朋数了衣久也没有数完, 他惒让你告诉他在区间 [2022,2022222022] 中有 多少个数…

WinDbg. From A to Z! 笔记(一)

原文链接: WinDbg. From A to Z! 文章目录 为什么使用WinDbg为什么通过本书学习底层原理简述Windows的调试工具一览dbghelp.dll -- Windows 调试助手dbgeng.dll -- 调试引擎接口 调试符号 (Debug Symbols)有哪些调试信息生成调试信息匹配调试信息调用堆栈 侵入式与非侵入式异常…

Axure RP 9.0教程: 基于动态面板的元件跟随来实现【音量滑块】

文章目录 引言I 音量滑块的实现步骤添加底层边框添加覆盖层基于覆盖层创建动态面板添加滑块按钮设置滑块拖动效果引言 音量滑块在播放器类APP应用场景相对较广,例如调节视频的亮度、声音等等。 I 音量滑块的实现步骤 添加底层边框 在画布中添加一个矩形框:500 x 32,圆…

Eclipse IDE for ModusToolbox™ 3.4环境通过JLINK调试CYT4BB

使用JLINK在Eclipse IDE for ModusToolbox™ 3.4环境下调试CYT4BB&#xff0c;配置是难点。总结一下在IDE中配置JLINK调试中遇到的坑&#xff0c;以及如何一步一步解决遇到的问题。 1. JFLASH能够正常下载程序 首先要保证通过JFLASH(我使用的J-Flash V7.88c版本)能够通过JLIN…

黑马点评项目

遇到问题&#xff1a; 登录流程 session->JWT->SpringSession->tokenRedis &#xff08;不需要改进为SpringSession&#xff0c;token更广泛&#xff0c;移动端或者前后端分离都可以用&#xff09; SpringSession配置为redis模式后&#xff0c;redis相当于分布式se…

wgcloud怎么实现服务器或者主机的远程关机、重启操作吗

可以&#xff0c;WGCLOUD的指令下发模块可以实现远程关机和重启 使用指令下发模块&#xff0c;重启主机&#xff0c;远程关机&#xff0c;重启agent程序- WGCLOUD

深度解析Spring Boot可执行JAR的构建与启动机制

一、Spring Boot应用打包架构演进 1.1 传统JAR包与Fat JAR对比 传统Java应用的JAR包在依赖管理上存在明显短板&#xff0c;依赖项需要单独配置classpath。Spring Boot创新的Fat JAR&#xff08;又称Uber JAR&#xff09;解决方案通过spring-boot-maven-plugin插件实现了"…

deepseek(2)——deepseek 关键技术

1 Multi-Head Latent Attention (MLA) MLA的核心在于通过低秩联合压缩来减少注意力键&#xff08;keys&#xff09;和值&#xff08;values&#xff09;在推理过程中的缓存&#xff0c;从而提高推理效率&#xff1a; c t K V W D K V h t c_t^{KV} W^{DKV}h_t ctKV​WDKVht​…

突破反爬困境:SDK架构设计,为什么选择独立服务模式(四)

声明 本文所讨论的内容及技术均纯属学术交流与技术研究目的&#xff0c;旨在探讨和总结互联网数据流动、前后端技术架构及安全防御中的技术演进。文中提及的各类技术手段和策略均仅供技术人员在合法与合规的前提下进行研究、学习与防御测试之用。 作者不支持亦不鼓励任何未经授…