【Linux】进度条与缓冲区

Linux下缓冲区的刷新

直击主题:缓冲区

关于缓冲区,我们在C/C++编程时所了解到的就是系统提供的一个暂存区,暂时存放我们的输入和输出,是一块不太大的空间,至于具体为什么要有这块空间,当然是为了提高系统的效率;

当然,在这里就不得不提一个概念,就是标准库函数和系统调用之间的关系;

printf就是一个标准输出函数,标准库函数一般是对系统调用的封装,而printf即是对write系统调用的封装,不过在调用write之前,加入了一个缓冲区,即我们现在所说的这个缓冲区,而printf实际是向用户空间的IO缓冲写,在满足条件的情况下(条件下面会说)才会调用write系统调用,这样也就提高了内核的效率。

当然,这只是一般情况,还有其它的情况,对于系统调用和标准库函数的关系,下面我推荐一篇比较好的博客,毕竟我的水平还不够,但上面所说的内容已经可以满足本片博客的需求了;

推荐博客:

http://blog.csdn.net/skyflying2012/article/details/10044343


缓冲区的大小以及刷新方式

缓冲区的类型有三种:

标准I/O 提供了3 种类型的缓冲区。

1,全缓冲区:这种缓冲区要求填满整个缓冲区后才进行I/O 系统调用操作。对于磁盘文件通常使用全缓冲区访问。第一次执行I/O 操作时,ANSI 标准的文件管理函数通过调用malloc 函数获得需使用的缓冲区。默认大小为8192。

2,行缓冲区:在这种情况下,当在输入和输出中遇到换行符时,标准I/O 库执行I/O系统调用操作。当流涉及一个终端时(例如标准输入和标准输出),使用行缓冲区。因为标准I/O 库收集的每行的缓冲区长度是固定的,只要填满了缓冲区,即使还没有遇到换行符,也将执行I/O 系统调用操作。默认行缓冲区大小为128 字节。

3,无缓冲区:标准I/O 库不对字符进行缓存。如果用标准I/O 函数写若干字符到不带缓冲区的流中,则相当于用write 系统调用函数将这些字符写至相关联的打开文件。标准出错流stderr 通常是不带缓冲区的,这使得出错信息能够尽快地显示出来。

                                    -----参考红黑联盟

既然上面提到了行缓冲区的大小,我们就可以尝试写个小程序来测试一下我们的Linux的行缓冲区的大小;

思路:首先得知道缓冲区的刷新方式,即怎样打印内容;

printf是一个行缓冲函数,先写到缓冲区,满足条件后,才将缓冲区刷到对应文件中,刷缓冲区的条件如下:
1 行缓冲区填满
2 写入的字符中有‘\n’ 
3 调用fflush手动刷新缓冲区
4 调用scanf要从缓冲区中读取数据时,也会将缓冲区内的数据刷新
5 当然,程序结束也会刷新缓冲区

现在,我们知道了缓冲区的刷新方式,先不管其它的,先来想办法确定缓冲区的大小,刚好,刷新方式的第一条,把缓冲区填满,然后自动就刷新出来了,那只要我们把缓冲区写满,我们可以得到一个缓冲区的大小,二话不说,先来试试;

写下下面的代码:

这里写图片描述

分析: 这个代码的运行结果是个死循环,相信你已经注意到了,这是我目前为止想到的比较笨也是唯一知道的办法,其中加入了一句usleep函数(不知道usleep函数可以去man —_—|||),是因为没有加的话,找不到写满行缓冲区刷新时的分割,加入这个等待时间的话,他会有一定的停顿(时间自己把握),这样我们就可以Ctral+c结束程序,将打印出的那部分放在一个空文件里,然后看这个文件的大小就知道行缓冲区的大小了,结果如下:

这里写图片描述

复制到一个空的文件名为size的文件中,然后stat看文件的大小;

这里写图片描述

分析: 可以看到文件的大小是1025个字节;即1KB的行缓冲区;


进度条的实现:

前面说了行缓冲区,缓冲区的刷新,那么下面这个进度条的实现就是对上面知识的应用;

插入一点 \r 和 \n 的区别:

1.回车换行符,是2个符。一个回车,一个换行。\r仅仅是回车,\n是换行。一个是控制屏幕或者从键盘的Enter键输入。另一个是控制“打印机”!
2.回车 = 光标到达最左侧,换行 = 移到下一行。如果只回车,打印的东西会覆盖同行以前的内容,如果只换行,打印的东西会在下一行的先一个位置继续。
3.\r实际是回到行首。\n如果下一行已经有了一些内容的话它会在那些内容的后边.因为一般情况下下一行是没有数据的,很多时候\n也就成了\r\n作用一样。

注意上面加粗的那句话,进度条的实现利用到了这一点,还有fflush强制刷新缓冲区;

代码:

这里写图片描述

然后编辑一个主函数进行调用,我在这里简单的运用了make和makefile,对于make和Makefile会在后面的深入学习中进行总结;

结果展示:
这里写图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值