fd与FILE以及fork缓冲问题

2023-05-16

一、文件描述符(fd)

1.文件描述符其实就是一个非负的小整数。是文件指针数组的下标。
2.让我们看一看0,1,2,…代表什么?

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

int main()
{
    char buf[1024];
    printf("fd0\n");
    ssize_t s=read(0,buf,sizeof(buf));
    if(s>0)
    {
        buf[s]=0;
        printf("fd1\n");
        write(1,buf,strlen(buf));
        printf("fd2\n");
        write(2,buf,strlen(buf));
        printf("fd3\n");
        write(3,buf,strlen(buf));
    }
    return 0;
}

这里写图片描述
从运行程序来看,文件描述符0,1,2是Linux默认情况下三个缺省打开的。3不是缺省的。
0,1,2对应的物理设备分别是键盘、显示器、显示器。

//标准输入、输出
执行一个shell命令行时通常会自动打开三个标准文件,
即标准输入文件(stdin),通常对应终端的键盘;
标准输出文件(stdout)和标准错误输出文件(stderr),这两个文件都对应终端的屏幕。

3.文件描述符如何做到找到对应文件的?
这里写图片描述
每个进程都有一个PCB,每一个PCB中都包含一个file指针,它指向一个文件结构体,结构体中包含了一个文件指针数组,每个元素都包含了一个指向打开文件的指针!,所以文件描述符就是该文件指针数组的下标,因此,我们只需要知道文件描述符,就可以通过文件描述符去找到指针指向的文件。

4.文件描述符的分配规则

在file_struct结构体中,找到当前没有被使用的最小的一个下标,作为新的文件描述符。
//文件描述符也是一种资源,这种分配规则可以很好的利用资源。

1)当没有关闭默认文件描述符时,新文件的文件描述符等于3。
2)当关闭了0时,新文件的文件描述符是0。
3)关闭使用close(0)

5.重定向
概念:将各种请求重新定个方向转到其它位置
分类:重定向有输出重定向(>)、输入重定向(<)、追加重定向(>>)。
⑴先看一个小程序,关闭文件描述符1,分配给新文件

#include <stdio.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdlib.h>
int main()
{
    close(1);
    int fd = open("myfile", O_WRONLY|O_CREAT, 00644); 
    if(fd < 0){
        perror("open");     
        return 1;
    }
    printf("fd: %d\n", fd); 
    fflush(stdout);
    close(fd);
    return 0;
}

⑵根据分配规则,新打开的文件接收到的文件描述符是1,但结果是什么呢?看下图↓
这里写图片描述
我们发现,fd:1本来是往屏幕输出的,可是它并没有,而是输出到了打开的文件中,我们把这种现象称为输出重定向。
重定向有输出重定向(>)、输入重定向(<)、追加重定向(>>)。
那它到底发生了什么?看下图↓
这里写图片描述
⑶printf是C库函数,本应该往stdout中输出,但此时fd:1的下标存放的是新文件的地址。也就是说标准输出被占用了,无法往显示器输出,这叫输出重定向。

二、FILE

1.FILE是在stdio.h定义的保存文件流信息的一个结构体类型
2.本质上访问文件都是通过fd访问的,库函数封装了fd,所以,FILE结构体内部肯定封装了fd。
3.fork缓冲问题。

//行缓冲:比如写入显示器中,输入的数先进入行缓冲区,当满足条件时,在进一步输出到屏幕。
//全缓冲;比如写入文件中。
//无缓冲

①使用三种操作方式(库函数、系统调用)往显示器打印数据

int main()
{
    const char *msg0="printf\n"; 
    const char *msg1="fwrite\n"; 
    const char *msg2="write\n";
    printf("%s", msg0);
    fwrite(msg1, strlen(msg0), 1, stdout); 
    write(1, msg2, strlen(msg2));
    fork();
    return 0;
}

这里写图片描述
②对进程进行输出重定向
这里写图片描述
为什么会出现这种现象呢?不应该都是出现两次吗?
答:当进程输出重定向到新文件时时,数据的缓冲方式由行缓冲转换为全缓冲,printf与fwrite(库函数自带缓冲区)先进入了全缓冲区,不会立即被刷新;write是系统调用,没有缓冲区,直接输出到了屏幕,当下一步执行fork()函数时,子进程的执行起点为fork之后,但此时父子数据会发生写时拷贝,所以当父进程全缓冲区准备刷新的时候,子进程也有了同样的一份数据,随机产生两份数据。那为什么子没有write数据呢?因为写时拷贝,只有在写入时,数据才被复制。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fd与FILE以及fork缓冲问题 的相关文章

  • QT 三角气泡提示框(文字自适应、自定义三角位置)

    文章目录 一 效果图二 实现代码1 调用示例2 BubbleTipsWidget h3 BubbleTipsWidget cpp 一 效果图 二 实现代码 1 调用示例 span class token keyword void span
  • QT 代码添加QScrollArea

    一 QScrollArea 一 这是一个控件容器类 xff0c 可以在UI中直接拖拽 xff0c 也可以使用代码进行添加 xff0c 当我们UI添加时 xff0c QScrollArea这个容器套了两层 xff0c 我们放入的控件 xff0
  • QML入门----创建qml项目(一)

    文章目录 导语一 选择菜单二 选择文件类型三 填写项目名称四 项目创建成功五 Hello World六 运行图 导语 今天开始学习qml xff0c 从hello world开始 xff0c 本来计划之前开始学的 xff0c 但是看了好多资
  • QML入门----基本语法(二)

    文章目录 基础语法1 import 导入语句2 Loader 一 类型二 对象1 id2 属性 xff08 property xff09 3 信号和信号处理器特性4 方法特性 function5 附加属性和附加信号处理器6 枚举 四 注释五
  • QML入门----图形动画基础(一)

    文章目录 一 图形动画基础1 颜色2 渐变 xff08 Gradient xff09 二 图片1 图片2 边界图片3 动态图片 三 缩放 旋转 平移变换1 使用属性2 高级变换 xff08 Transform xff09 四 状态改变使用过
  • QT Signal and slot arguments are not compatible

    一 原因 信号和槽绑定的参数不同 signals span class token operator span span class token keyword void span span class token function run
  • QML入门----图形动画基础(二)

    文章目录 导语一 混合效果二 颜色效果1 亮度对比度 xff08 BrightnessContrast xff09 2 颜色叠加3 着色4 饱和度 三 渐变效果 xff08 Gradient xff09 四 阴影效果五 模糊效果六 动感模糊
  • EXCEL基本办公操作 (求和、相除、填充日期、交换列、排序)

    文章目录 一 求和二 相除三 自动填充日期四 交换列五 进行排序 一 求和 1 拖动鼠标选中 2 同时按住 alt 跟 61 二 相除 假如要计算A列除以B列 1 先选中显示结果的框 2 在上面的框输入 61 号 xff0c 然后点击A1位
  • Ubuntu的VirtualBox虚拟机怎么识别物理机的U盘?我教你。

    首先确保 你的VBOX虚拟机安装了扩展 1 到官网上下载扩展吧 2 用VBOX打开扩展包 3 打开VBOX管理器 xff0c 点击设置 4 新建一个usb筛选器 xff0c 名字随便起 最后点击确定 正常关闭 你的虚拟机 xff0c 然后重
  • QML入门----设计器详解(拖拽添加控件)

    文章目录 导语1 基本视图2 文件类型 一 界面说明1 库 xff08 Library xff09 2 导航 xff08 Navigator xff09 3 属性 xff08 Properties xff09 4 连接视图 导语 设计器的基
  • C++11 非常方便的特性

    文章目录 C 43 43 11一 nullptr1 含义2 作用3 NULL存在的问题 二 auto1 含义2 限制3 使用场景 三 lambda1 含义2 优点3 用法 四 基于范围的for循环1 作用2 用法3 循环内更改数组 C 43
  • QML入门----C++与QML交互快速应用

    文章目录 前言一 Qt中有关QML的C 43 43 类1 QQmlEngine2 QQmlContext3 QQmlComponent4 QQmlExpresssssion 二 其他1 使用C 43 43 属性 xff08 Q PROPER
  • QML错误:Component is not ready

    一 原因 终极原因 xff1a 组件没有构建好 xff0c 有可能是加载的QML路径不对 xff0c 或者是QML代码错误 xff0c 或者是QML组件还没有加载完 二 解决办法 打印详细错误 QQmlEngine engine span
  • QT 打开程序闪烁cmd窗口

    包含多种原因 xff0c 我的原因是Pro文件多写了一些其他的 xff0c 删除了下面这句OK了 DISTFILES span class token operator 43 span span class token operator 6
  • QT UTC(T和Z格式)时间转换为北京时间

    一 UTC 协调世界时 xff0c 又称世界统一时间 世界标准时间 国际协调时间 由于英文 xff08 CUT xff09 和法文 xff08 TUC xff09 的缩写不同 xff0c 作为妥协 xff0c 简称UTC 和北京时间相差八小
  • QT 文件操作大全

    文章目录 常用文件模式一 创建文件二 读文件三 写文件四 清空文件夹五 计算文件夹个数六 计算文件夹总大小七 转换大小为B KB M G八 批量修改文件名 常用文件模式 模式含义QIODevice ReadOnly只读方式QIODevice
  • QT QScrollArea 滑动到指定item位置

    一 QT自带的api QListWidget QTableWidget QTreeWidget都有自带的api可以调用 xff0c 如下示例 但是当自定义一个QScrollArea区域 xff0c 布局中插入多个item时 xff0c 就需
  • 马克飞象常用操作(markdown )

  • QT 移入控件展示卡片

    功能 xff1a 移入widget显示卡片 xff0c 并且可以进入卡片不消失 xff08 widget与卡片距离离得很近 xff09 xff0c 移出卡片才离开 span class token keyword bool span spa
  • 树莓派pico入门第一站:让主板上的小灯闪起来。(附代码)

    首先配置你的树莓派pico xff0c 把它插在你的电脑上 xff0c 你的电脑会多出来一个 U盘 xff0c 把这个文件复制 xff0c 粘贴 到你的树莓派pico里面 xff0c 你多出来的 U盘 会自动 消失 xff0c 这时候 xf

随机推荐

  • QT 网格布局插入固定列数的item

    一 场景 在网格布局插入固定列数的item xff0c 比如三列item xff0c 根据item的总数计算 span class token macro property span class token directive hash s
  • QT QMetaEnum枚举与字符串互转

    一 示例 span class token macro property span class token directive hash span span class token directive keyword include spa
  • QT 抓取widget转换为图片

    QString folder span class token operator 61 span span class token class name QStandardPaths span span class token operat
  • window11 安装linux子系统(一键安装)并连接到vs code

    文章目录 一 window 使用linux环境的几种方式二 安装wsl1 进入这个目录下 xff0c 将cmd exe已管理员身份运行2 命令行输入以下命令 xff0c 然后重启计算机3 再次已管理员身份打开 xff0c 执行命令 xff0
  • QT 利用URL Protocol实现网页调起本地程序

    一 QT 安装时脚本注入注册表或者自己添加 span class token comment 依次为目录 键 值 xff0c 34 URL Protocol 34 这个键必须有 span WriteRegStr HKCR span clas
  • PC 配置jenkins自动打包

    文章目录 一 下载jenkins运行环境二 下载jenkins三 安装 qt 5 12 2 和 VS 2017四 安装git并配置gitlab五 jenkins配置git 一 下载jenkins运行环境 java jdk 11 镜像下载地址
  • 心系Flyme

    我来自陕西省神木县 xff0c 大学我考入了陕西科技大学 xff0c 成为了一名信息与计算科学专业的学生 xff0c 希望在以后的道路中 xff0c 通过我自己的努力 xff0c 提升自己的价值 在大二大三学习编程 xff0c 希望自己可以
  • C语言的编译链接过程

    编写的一个C程序 xff08 源程序 xff09 xff0c 转换成可以在硬件上运行的程序 xff08 可执行程序 xff09 xff0c 需要进行翻译环境和运行环境 翻译环境则包括两大过程编译和链接 xff0c 经过编译和链接过程便可形成
  • 函数的调用过程(栈帧的创建和销毁)

    为了更好地认识函数的调用过程 xff0c 我们可以用反汇编代码去理解学习 一 基本概念 1 栈帧 xff08 过程活动记录 xff09 xff1a 是编译器用来实现函数调用的一种数据结构 xff0c 每个栈帧对应一个未运行完的函数 xff0
  • 树莓派pico刚买来怎么用?

    第一次使用 xff0c 首先按住主板上的白色按钮 xff0c 然后另一只手把数据线插在主板上 xff0c 直到你的电脑提示有新设备输入 xff0c 提示可以是声音 xff0c 可以是设备管理器多了一个U盘 要想得到提示 xff0c 你要打开
  • C语言动态顺序表

    顺序表是将表中的节点依次存放在计算机内存中一组地址连续的存储单元中 xff0c 表可以动态增长 xff0c 尾插元素 xff0c 尾删元素 xff0c 头插元素 xff0c 头删元素 xff0c 打印元素 xff0c 查找元素 xff0c
  • C语言笔记1

    假定程序运行环境为VC6 0 xff0c 缺省为四字节对齐 xff0c CPU xff08 32小字节序处理器 xff09 1 char x 61 34 ab0defg 34 char y 61 39 a 39 39 b 39 39 0 3
  • 【C++三大特性】继承

    如有疑问 xff0c 欢迎讨论 xff0c QQ xff1a 1140004920 一 继承的概念 1 原有的类为基类 xff0c 又称父类 xff0c 对基类进行扩展产生的新类称为派生类 xff0c 又称子类 xff0c 继承可以使代码复
  • C++实现顺序表及双向链表

    顺序表 include lt iostream gt include lt assert h gt using namespace std typedef int DataType class SeqList public 默认的构造函数
  • 二叉树

    一 二叉树 是结点的一个有限集合 xff0c 每个根结点最多只有两颗子树 xff0c 二叉树有左右之分 xff0c 子树的次序不能颠倒 二 二叉树的种类 1 满二叉树 xff1a 每个结点都有左右子树 xff0c 且叶结点都在同一层 2 完
  • 进程间通信----管道、消息队列、共享内存、信号量

    一 进程间通信 xff08 Inter Process Communication xff09 1 目的 1 数据传输 2 资源共享 3 通知事件 4 进程控制 注 xff1a 每个进程都有各自不同的用户地址空间 xff0c 进程之间要交换
  • 进程基本概念、进程地址空间

    强调内容今天来谈一谈进程的一些基本概念 xff0c 认识一些进程状态 xff0c 重新认识一下程序地址空间 xff08 进程地址空间 xff09 xff0c 进程调度算法 xff0c 环境变量等属性 一 进程 1 什么是进程 xff1f 程
  • 何为缓存?

    一 缓存 xff08 cache xff09 1 概念 xff1a 数据交换的缓冲区 xff08 称作Cache xff09 缓存是一块内存芯片 xff0c 具有极快的存取速率 xff0c 它是硬盘内部存储和外界接口之间的缓冲器 xff0c
  • 计算机的组成

    一 冯诺依曼系统 1 计算机硬件 由运算器 控制器 存储器 输入设备 输出设备组成 2 计算机内部采用二进制表示指令和数据 3 注 xff1a 1 输入设备 xff1a 键盘和鼠标等 2 输出设备 xff1a 显示屏 xff0c 打印机等
  • fd与FILE以及fork缓冲问题

    一 文件描述符 fd 1 文件描述符其实就是一个非负的小整数 是文件指针数组的下标 2 让我们看一看0 xff0c 1 xff0c 2 xff0c 代表什么 xff1f span class hljs preprocessor includ