标准的I/O缓冲:全缓冲,行缓冲,无缓冲

news/2024/11/9 0:45:29/

今天在学习进程时遇到关于一个I/O缓冲区的的问题,和大家分享一下,首先举个简单的例子:

#include <stdio.h>
int main()                                                                      
{printf("hello,world!");_Exit(0);
}

编译成功后却不出现hello,world,这是为什么呢,注意,在代码中printf语句打印hello,world的字符串最后面没带换行符.而且最后调用了_Exit函数,这导致了在终端上显不出hello,world. 首先介绍关于标准I/O的几种缓冲机制: 1.全缓冲:全缓冲指的是系统在填满标准的I/O缓冲区后才进行实际的I/O操作,注意,对于驻留在磁盘上的文件来说通常是由标准的I/O库实施全缓冲. 2.行缓冲: 在这种情况下,标准的IO在输入和输出中遇到换行符执行IO操作;注意,当流涉及终端时,都使用行缓冲. 3.无缓冲:无缓冲指的是标准的IO库不对字符进行缓冲存储,注意,标准的出错流stderr通常是无缓冲的. 在看几个退出函数: 1.exit(),调用exit函数之后,它首先执行一系列的清理处理,包括调用执行各种终止处理程序,关闭所有标准IO流等,然后进入内核; 2._exit().与exit不同的是,它不进行清理直接进入内核此函数由POSIX.1说明,放在unistd.h里面. 3._Exit ()。同样,它也不进行清理工作而直接进入内核。此函数跟exit一样由ISO C说明,放在stdlib.h里面。 所以可以有很多方法修正这段代码: 1.在hello,world后加一个换行符,此时行缓冲遇到换行符\n.执行实际IO操作. 2.调用exit()函数,让它帮我们进行相应的IO操作,也就是把_Exit(),换成exit(); 3.改变标准的输出流的默认缓冲区,这个要用到函数setvbuf(),那就先介绍以下这个函数吧: #include <stdio.h> void setbuf(FILE *stream, char *buf); void setbuffer(FILE *stream, char *buf, size_t size); void setlinebuf(FILE *stream); int setvbuf(FILE *stream, char *buf, int mode, size_t size); 函数说明: 1.对于setbuf()函数,buf指出的缓冲区长度由头文件stdio.h中定义的 宏BUFSIZE的值决定,缺省值为512字节。当选定buf为空时,setbuf函数将使的文件I/O不带缓冲。 2.setvbuf函数,则由 malloc函数来分配缓冲区。参数size指明了缓冲区的长度(必须大于0),而参数type则表示了缓冲的类型,其值可以取如下值: 3.在打开文件流后,读取内容之前,调用setbuffer()可用来设置文件流的缓冲区。参数stream为指定的文件流,参数buf指向自定的缓冲区起始地址,参数size为缓冲区大小。 4. setlinebuf()用来设置文件流以换行为依据的缓冲IO,即行缓冲。 type 值 含义 _IOFBF 文件全部缓冲,即缓冲区装满后,才能对文件读写 _IOLBF 文件行缓冲,即缓冲区接收到一个换行符时,才能对文件读写 _IONBF 文件不缓冲,此时忽略buf,size的值,直接读写文件,不再经过文件缓冲区缓冲 所以我们可以通过调用setvbuf函数,把标准的输出流默认的行缓冲变成无缓冲 setvbuf(stdout, NULL, _IONBF, 0); 现在说一说我今天遇到的具体的问题吧,大家都知道,fork一个子进程,子进程会复制父进程的许多资源(这个自己查),最重要的是它会复制父进程的缓冲区, 举个例子吧,

#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
extern char **environ;
int main()
{pid_t pid;int stat_val;char *argv[]={"ls","-al","/",NULL};//printf("exec函数族实例:\n");//去掉注释;printf("exec函数实例:");pid=fork();switch(pid) {case -1:perror("进程创建失败!\n");exit(1);case 0:printf("子进程正在运行!\n");printf("我的ID=%d,父亲的ID=%d\n",getpid(),getppid());   //execve("/bin/ls",argv,environ);//execv("/bin/ls",argv);//execvp("ls",argv);//execl("/bin/ls","ls","-al","/",NULL);
//              execlp("ls","ls","-al","/",NULL);execvp("ls",argv);printf("如果exec函数调用成功,这一句不会被执行!\n");exit(0);default:printf("父进程正在运行!\n");break;                                                                                                                          }       wait(&stat_val);return 0;
}

编译运行:

yang@liu:~/Linux C$ gcc processimage1.c 
yang@liu:~/Linux C$ ./a.out
exec函数实例:父进程正在运行!
exec函数实例:子进程正在运行!
我的ID=6032,父亲的ID=6031
总用量 105
drwxr-xr-x  24 root root  4096  7月 13 12:11 .
drwxr-xr-x  24 root root  4096  7月 13 12:11 ..
drwxr-xr-x   2 root root  4096  5月 31 11:42 bin

然后把注释写//去掉注释那一行注释去掉,注释掉下面那一行: 编译运行:

exec函数族实例:
父进程正在运行!
子进程正在运行!
我的ID=7354,父亲的ID=7353
总用量 105
drwxr-xr-x  24 root root  4096  7月 13 12:11 .
drwxr-xr-x  24 root root  4096  7月 13 12:11 ..
drwxr-xr-x   2 root root  4096  5月 31 11:42 bin
drwxr-xr-x   4 root root  1024  5月 31 14:20 boot

第一次没有加进行加\n,所以父进程运行后"exec函数族实例:"就存在于父进程的缓冲区中,当fork后,子进程也复制了父进程的缓冲区,所以输出了两次"exec函数族实例", 第二次,加了\n,进行了行缓冲清理,所以只由父进程输出一次;


http://www.ppmy.cn/news/428292.html

相关文章

7-2 武林盟主 ,7-3 数组循环移位,7-4 又一个往返跑方阵 7-8 输出成绩信息

目录 7-2 武林盟主 (10 分) 输入格式: 输出格式: 输入样例: 输出样例: 7-3 数组循环移位 (10 分) 输入格式: 输出格式: 输入样例: 输出样例: 7-4 又一个往返跑方阵 (10 分) 输入格式: 输出格式: 输入样例1: 输出样例1: 输入样例2: 输出样例2: 7-8 输出成绩信…

从AliSQL切换到MySQL出现Unknown collation: 'utf8mb4_unicode_520_ci

记一次从AliSQL切换到MySQL出现Unknown collation: utf8mb4_unicode_520_ci 出现错误的原因 以前一直用的AliSQL&#xff0c;AliSQL是阿里根据MySQL优化的&#xff0c;可以说是优化版本&#xff0c;性能更高&#xff0c;更加稳定&#xff0c;如果优化完还和原版是一样&#x…

备忘

python十进制转16进制&#xff1a;python -c "print hex(28285)" 程序远程调试:-Xdebug -Xrunjdwp:transportdt_socket,servery,address"8000" 程序运行时间&#xff1a;ps -eo pid,lstart,etime | grep 5176 lstart 启动时间 etime 运行多长时间 硬…

pta武林盟主 c(gcc)

在传说中的江湖中&#xff0c;各大帮派要选武林盟主了&#xff0c;如果龙飞能得到超过一半的帮派的支持就可以当选&#xff0c;而每个帮派的结果又是由该帮派帮众投票产生的&#xff0c;如果某个帮派超过一半的帮众支持龙飞&#xff0c;则他将赢得该帮派的支持。现在给出每个帮…

Python练习题六

博主&#xff1a;&#x1f44d;不许代码码上红 欢迎&#xff1a;&#x1f40b;点赞、收藏、关注、评论。 文章目录 一、判断双对称矩阵二、武林盟主三、交换数组元素四、简单的归并五、保持数列有序六、部分逆置七、n马n担问题八、Fibonacci分数序列九、最小回文数十、猴子吃桃…

网络程序设计课程项目学习总结-SA16225018-曾龙飞

项目概要 本项目主要可分为两大方面&#xff1a; 1 .血常规检查报告的OCR识别 相关链接&#xff1a;神经网络实现手写字符识别系统点击打开链接 2.根据OCR识别的血常规数据预测性别和年龄&#xff08;本例中使用的是Spark平台下的朴素贝叶斯算法&…

吐槽冰火周刊I

经过漫长的等待&#xff0c;在即将入夏的时候&#xff0c;维斯特洛的永夜即将到来&#xff0c;这是一场关于活人与死人的战争。 我不是专业的剧评人&#xff0c;所以这不是逐帧分析和预测&#xff0c;仅仅是看到这部分的时候&#xff0c;一些梗或是有意思的点&#xff0c;欢迎一…

【龙飞】Spring Security源码分析一:Spring Security认证过程

摘要: 原创出处 http://niocoder.com/2018/01/02/Spring-Security源码分析一-Spring-Security认证过程/ .欢迎转载&#xff0c;保留摘要&#xff0c;谢谢&#xff01; Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供…