Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我应该在C中设置stdout和stdin为无缓冲吗?_C_Buffer_Stdout_Stdin - Fatal编程技术网

我应该在C中设置stdout和stdin为无缓冲吗?

我应该在C中设置stdout和stdin为无缓冲吗?,c,buffer,stdout,stdin,C,Buffer,Stdout,Stdin,由于stdin和stdout有时缓冲printf,scanf和getchar不会执行。我通常使用fflush(stdout)刷新输出缓冲区,但代码可能因此变得非常不可读。如果我使用setbuf(stdin,NULL)和setbuf(stdout,NULL)设置stdin和stdout无缓冲我会让我的程序执行得更好还是更差?让stdin或stdout完全无缓冲会让你的程序在处理大量文件输入/输出时执行得更差。大多数I/O请求将按系统调用逐字节分解 请注意,缓冲不会导致不执行printf、scanf

由于
stdin
stdout
有时缓冲
printf
scanf
getchar
不会执行。我通常使用
fflush(stdout)
刷新输出缓冲区,但代码可能因此变得非常不可读。如果我使用
setbuf(stdin,NULL)
setbuf(stdout,NULL)设置
stdin
stdout
无缓冲
我会让我的程序执行得更好还是更差?

stdin
stdout
完全无缓冲会让你的程序在处理大量文件输入/输出时执行得更差。大多数I/O请求将按系统调用逐字节分解

请注意,缓冲不会导致不执行
printf
scanf
getchar
printf
到最终目标的输出可能只是延迟,因此通过
scanf
getchar
的输入操作可能会在没有提示的情况下发生

还请注意,从终端将输入设置为无缓冲可能无效,因为终端本身通过
stty
ioctl
执行其自己的缓冲控制

大多数C库都有一个漏洞,当从
stdin
读取数据时,会导致
stdout
被刷新,这需要从系统中获取数据,但是C标准中没有规定这种行为,因此一些库没有实现它。向
fflush(stdout)添加调用是安全的在输入操作之前和临时消息(如进度表)之后。在大多数情况下,最好让C启动程序根据与
stdin
stdout
流关联的系统句柄类型来确定适当的缓冲策略。常见的默认设置是设备的行缓冲,文件的行缓冲大小为
BUFSIZ

要了解潜在的性能影响,请编译以下幼稚的
ccat
程序:

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

int main(int argc, char *argv[]) {
    int c, size;

    if (argc > 1) {
        if (!strcmp(argv[1], "BUFSIZ"))
            size = BUFSIZ;
        else
            size = strtol(argv[1], NULL, 0);

        if (size == 0) {
            /* make stdin and stdout unbuffered */
            setvbuf(stdin, NULL, _IONBF, 0);
            setvbuf(stdout, NULL, _IONBF, 0);
        } else
        if (size > 0) {
            /* make stdin and stdout fully buffered */
            setvbuf(stdin, NULL, _IOFBF, size);
            setvbuf(stdout, NULL, _IOFBF, size);
        } else {
            /* make stdin and stdout line buffered */
            setvbuf(stdin, NULL, _IOLBF, -size);
            setvbuf(stdout, NULL, _IOLBF, -size);
        }
    }
    while ((c = getchar()) != EOF) {
        putchar(c);
    }
    return 0;
}
#包括
#包括
#包括
int main(int argc,char*argv[]){
int c,大小;
如果(argc>1){
如果(!strcmp(argv[1],“BUFSIZ”))
尺寸=BUFSIZ;
其他的
size=strtol(argv[1],NULL,0);
如果(大小==0){
/*使标准输入和标准输出无缓冲*/
setvbuf(标准输入,空,0);
setvbuf(标准输出,空,0);
}否则
如果(大小>0){
/*使标准输入和标准输出完全缓冲*/
setvbuf(标准输入,空,IOFBF,大小);
setvbuf(标准输出,空值,_IOFBF,大小);
}否则{
/*使标准输入和标准输出线缓冲*/
setvbuf(标准输入,空值,_IOLBF,-大小);
setvbuf(标准输出,空值,_IOLBF,-大小);
}
}
而((c=getchar())!=EOF){
普查尔(c);
}
返回0;
}
多次复制大文件以最小化文件缓存的副作用的时间程序执行

在Debian linux设备上,我获得了3.8MB文本文件的以下计时:

chqrlie@linux:~/dev/stackoverflow$ time wc w
 396684  396684 3755392 w
real    0m0.072s
user    0m0.068s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time cat < w > ww
real    0m0.008s
user    0m0.000s
sys     0m0.004s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat < w > ww
real    0m0.060s
user    0m0.056s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0x100000 < w > ww
real    0m0.060s
user    0m0.058s
sys     0m0.000s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat 0 < w > ww
real    0m5.326s
user    0m0.632s
sys     0m4.684s

chqrlie@linux:~/dev/stackoverflow$ time ./ccat -0x1000 < w > ww
real    0m0.533s
user    0m0.104s
sys     0m0.428s
chqrlie@linux:~/dev/stackoverflow$time wc w
396684 396684 3755392 w
实际0.072s
用户0m0.068s
系统0m0.000s
chqrlie@linux:~/dev/stackoverflow$time catww
实0.008s
用户0.000s
系统0m0.004s
chqrlie@linux:~/dev/stackoverflow$time./ccatww
实0.060s
用户0m0.056s
系统0m0.000s
chqrlie@linux:~/dev/stackoverflow$time./ccat 0x100000ww
实0.060s
用户0m0.058s
系统0m0.000s
chqrlie@linux:~/dev/stackoverflow$time./ccat 0ww
实际0m5.326s
用户0.632s
系统0m4.684s
chqrlie@linux:~/dev/stackoverflow$time./ccat-0x1000ww
实际0.533s
用户0.104s
系统0m0.428s
如你所见:

  • stdin
    stdout
    设置为无缓冲会导致程序的速度降低近100倍
  • 使用行缓冲的速度降低了10倍(因为行很短,平均为9到10字节)
  • 使用更大的缓冲区不会显示出任何改善,时序差异不显著
  • 朴素的实现速度相当快,但真正的
    cat
    实用程序使用更快的API,执行时间要快6倍
作为结论:不要将
stdin
stdout
设置为unbuffered,即使是中等大小的文件,它也会显著影响性能