Linux缓冲输出问题


Linux缓冲输出问题
 
在网上看到一段这样的代码,这段代码本身是有问题的,我看了一下,觉得没什么问题,结果编译运行一下  www.2cto.com  
确实报错,查了一下linux下缓冲方面的资料,跟大家分享一下,最后说下这段代码的问题所在
 
当一个程序运行输出时,是否有必要将输出立即展示给用户?这个问题根据用户需要而定
 
举个例子:
    假设一个程序输出到终端,向终端用户提问,要求用户回答;或者向用户给出提示,即让用户指定应该键入什么内容,这时候,程序
的输出应该立即展示给用户。  www.2cto.com  
    另一种情况是,程序输出到一个文件,那么只要程序结束前最后的结果全部输出到了文件就可以了。
综上,程序输出有两种方式:一种是立即处理方式,另一种是先缓存起来,然后再大批写入的方式,也就是我们所说的缓冲方式。比较一下两种方式的优缺点。立即方式往往会造成较高的系统负担,因为磁盘IO一般比较慢;缓冲方式允许我们将数据写入文件或磁盘之前先将要写入的内容保存到一个缓冲区然后待缓冲区溢出再一次将缓冲区的内容写入文件,这样减少了磁盘IO的次数,提高的系统的效率。
 那么缓冲区该设置多大呢?C语言实现允许程序员控制产生的输出数据量,也就是可以自定义缓冲区的大小,是通过函数setbuf()实现的
。例如下面代码段中的setbuf(stdout,buf)就是将要写入标准输出的内容缓冲到buf中,待buf溢出再写入stdout的,然后清空buf,如此循环直至结束。
 
#include <stdio.h>
 main()
{
int c;
char buf[BUFSIZ];
setbuf(stdout, buf);
       while((c=getchar())!=EOF)
            putchar(c);
}
 
这段断码的问题在哪儿呢?每次缓冲区溢出时将缓冲区的内容写入到文件,然后清除缓冲区,那么最后一次清除缓冲区发生在什么时间?答案是main()函数返回之后,main函数返回程序不是立即结束,程序把控制权交回操作系统之前c运行时库必须进行清理工作,而缓冲区buf的清理就发生在此时。因为buf是定义在main中的局部变量,清理buf时,main()函数已经返回了,自然找不到buf了,所以程序出错。这也是c语言容易出错的地方。
 
解决办法有两个:
            1. 把buf声明为static类型,及全局型:static char buf[BUFSIZ]
#include <stdio.h>
 main()
{
int c;
static char buf[BUFSIZ];
setbuf(stdout, buf);
       while((c=getchar())!=EOF)
            putchar(c);
}
            2.用malloc函数动态分配buf的内存空间:setbuf(stdout, malloc(BUFSIZ)),不用担心malloc函数分配内存失败,malloc失败会
            返回NULL,这时会关闭缓冲,linux下有三种缓冲方式:行缓冲,全缓冲,无缓冲
#include <stdio.h>
#include <stdlib.h>
 main()
{
int c;
char buf[BUFSIZ];
setbuf(stdout, malloc(BUFSIZ));
       while((c=getchar())!=EOF)
            putchar(c);
}
 

相关内容

    暂无相关文章