首页 > 系统相关 >Linux系统编程—I/O缓冲区(C语言实现)

Linux系统编程—I/O缓冲区(C语言实现)

时间:2024-10-08 22:52:22浏览次数:9  
标签:fp 缓冲 写入 C语言 Linux 缓冲区 数据 setvbuf

I/O缓冲区

进程的I/O缓冲区机制是计算机操作系统中一个重要的概念,它涉及到数据在内存和外设之间的传输。以下是关于进程的I/O缓冲区机制的详细解释:

1.定义与作用

  1. 定义:I/O缓冲区是指在内存里开辟的一块区域,用来存放接收用户输入和用于计算机输出的数据,以减小系统开销和提高外设效率。

  2. 作用

    • 平滑I/O需求峰值:通过缓冲区,可以使得数据的传输更加平滑,避免因为I/O设备的速度差异而导致的数据传输瓶颈。
    • 提高系统速度:使用缓冲区可以使得用户进程在下一数据块读取的同时,处理已读入的数据块,从而提高系统的整体速度。

2.缓冲区的工作原理

  1. 数据读写过程

    • 当进程需要读取数据时,它向操作系统发出请求,操作系统随即向磁盘控制硬件发出命令,要求其从磁盘读取数据。磁盘控制器把数据直接写入内核内存缓冲区(这一步通过DMA完成,无需主CPU协助)。
    • 一旦磁盘控制器把缓冲区装满,内核即把数据从内核空间的临时缓冲区拷贝到进程执行read()调用时指定的缓冲区。
    • 当进程需要写入数据时,它先把数据写入到缓冲区中,然后操作系统在适当的时候将数据从缓冲区传输到外设中。
  2. 用户空间与内核空间

    • 用户空间是常规进程所在区域,是非特权区域,该区域的代码不能直接访问硬件设备。
    • 内核空间是操作系统所在区域,有特别的权利,能与设备控制器通讯,控制用户区域进程的运行状态等。所有I/O都直接或间接通过内核空间完成。

3.缓冲模式

C标准库中的缓冲模式主要有三种:

  1. 全缓冲(Fully Buffered):数据填满缓冲区后才进行实际的I/O操作。通常用于文件操作。
  2. 行缓冲(Line Buffered):遇到换行符(\n)或缓冲区满时,进行实际的I/O操作。通常用于终端输入/输出(如标准输入和标准输出)。
  3. 无缓冲(Unbuffered):每个I/O操作都直接进行,不使用缓冲区。通常用于一些需要实时性的场景。

设置缓冲模式

可以使用setvbuf函数来设置缓冲模式和缓冲区。setvbuf函数的原型如下:

void setvbuf(FILE *stream, char *buf, int mode, size_t size);
  • stream:指向FILE对象的指针,表示要设置缓冲模式的文件流。
  • buf:用户提供的缓冲区,如果为NULL,则分配一个指定大小的缓冲区。
  • mode:缓冲模式,可以是以下三个宏之一:
    • _IOFBF:全缓冲
    • _IOLBF:行缓冲
    • _IONBF:无缓冲
  • size:缓冲区的大小,以字节为单位。

示例代码

以下是一个示例代码,演示如何设置不同的缓冲模式:

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp;
    char buffer[1024];

    // 打开文件用于写入
    fp = fopen("example.txt", "w");
    if (fp == NULL) {
        perror("Failed to open file");
        return EXIT_FAILURE;
    }

    // 设置全缓冲模式,使用自定义缓冲区
    setvbuf(fp, buffer, _IOFBF, sizeof(buffer));
    fprintf(fp, "This is a fully buffered output.\n");
    // 此时数据可能还未写入文件,因为缓冲区未满

    // 强制刷新缓冲区,确保数据写入文件
    fflush(fp);

    // 设置行缓冲模式
    setvbuf(stdout, NULL, _IOLBF, 0);
    printf("This is a line buffered output.\n");
    // 数据在遇到换行符时写入标准输出

    // 设置无缓冲模式
    setvbuf(stderr, NULL, _IONBF, 0);
    fprintf(stderr, "This is an unbuffered output.\n");
    // 数据立即写入标准错误输出

    // 关闭文件
    fclose(fp);

    return EXIT_SUCCESS;
}

刷新缓冲

fflush函数用于刷新缓冲区,将缓冲区中的数据立即进行I/O操作。fflush函数的原型如下:

int fflush(FILE *stream);
  • stream:指向FILE对象的指针,如果为NULL,则刷新所有打开的文件流。

注意事项

  • 使用自定义缓冲区时,要确保缓冲区在文件流使用期间有效。
  • 在多线程环境中,对同一个文件流进行并发访问时,要谨慎使用缓冲区和fflush,以避免数据竞争和未定义行为。

通过理解C语言中的I/O缓冲区机制和如何使用setvbuffflush函数,可以更好地控制数据的读写行为,提高程序的效率和可靠性。

标签:fp,缓冲,写入,C语言,Linux,缓冲区,数据,setvbuf
From: https://blog.csdn.net/weixin_45706195/article/details/142771441

相关文章

  • 【C语言】输出数据的二进制存储形式
        说在前面:是一个C语言新手,很新的新手,在这个专栏记录一些探索过程    今天学习中学到类型转换,将int和short类型赋值给char类型变量时,因为想要清楚看到隐式转换的结果,产生了写一个东西来输出数据在计算机中的二进制存储形式的想法,以下为尝试过程一、首先想......
  • 第十三篇:linux中的特殊符号
    引号系列引号含义 单引号单引号里面的内容会原封不动的输出什么都不扩展双引号与单引号类似,对双引号里面的特殊符号会进行解析,对于{}花括号不能解析允许部分扩展不加引号和双引号类似,支持花括号的通配符 反引号优先执行,先执行反引号里面的命令 ......
  • Linux主机创建新用户并添加root权限
    1.添加用户设置密码useradd-d<homedir>-m-s/bin/bash<username>passwd<username><password>#为该用户设定密码为<password>useradd参数<homedir>:用户家目录,一般为/home/username-s:指定shell到/bin/bash-d:指定其home目录为<homedir>-m:如果指定的home目录......
  • C语言——static 关键字与 const 关键字
    static静态的        一、static修饰局部变量——称为静态局部变量                static改变了局部变量的生命周期(本质上是改变了变量的存储类型),当被static修饰时,局部变量由栈区存放到了静态区。voidtest(){intnum=1;printf("%d......
  • Linux中各种查看
    查看命令lsls :简单列出当前目录下的文件和子目录。ls目录路径 :列出指定目录下的内容。ls-l :以长格式显示详细信息,包括文件权限、所有者、大小、修改时间等。ls-a :显示包括隐藏文件(以 . 开头的文件和目录)。ls-h :以更易读的方式显示文件大小(如 K 、M 、......
  • Linux 网络管理-常见网络管理命令与工具
    Linux常用命令-网络管理常见网络管理命令与工具ip命令安装:aptinstalliproute2或dnfinstalliproute2ifconfig安装:aptinstallnet-tools或dnfinstallnet-toolsifconfig包含了常用的网络管理功能,包括网络接口的启停、网络参数的配置等,但是ifconfig的配置是临......
  • 实验2 C语言分支与循环基础应用编程-1
    任务一#include<stdio.h>#include<stdlib.h>#include<time.h>#defineN5#defineN1397#defineN2476#defineN321intmain(){intcnt;intrandom_major,random_no;srand(time(NULL));//以当前系统时间作为随机种子cnt=0;......
  • 宝塔平替:1Panel-新一代的 Linux 服务器运维管理面板(附优惠码/推荐码)
    什么是1Panel1Panel是一款开源,现代化的新一代的Linux服务器运维管理面板!1Panel可以帮你实现的功能:高效管理:用户可以通过Web图形界面轻松管理Linux服务器,实现主机监控、文件管理、数据库管理、容器管理等功能;快速建站:深度集成开源建站软件WordPress和Halo,域名绑定、S......
  • Linux csplit命令
    csplit命令在Linux中用于将文件分割成多个部分,基于指定的模式或固定数量的行。与split命令不同,csplit允许更复杂的分割条件,例如基于正则表达式匹配或特定字符的出现次数。基本语法csplit[选项]文件名模式文件名:要分割的文件。模式:分割文件的依据,可以是正则表达式或数字。......
  • Linux文件系统
    目录一、认识磁盘​二、操作系统对磁盘进行逻辑抽象1.扇区数组sectordisk_array[N]2.逻辑区块数组LBAblocks[N]3.磁盘分区三、文件系统1.文件系统结构2.如何拿到文件inode号?3.如何确定文件在哪个分区?一、认识磁盘一个磁盘由多个盘片组成,每个盘片有两个盘面和一......