理解fflush()和问题的与它相关的必要 [英] Understanding the need of fflush() and problems associated with it

查看:157
本文介绍了理解fflush()和问题的与它相关的必要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是一个示例code使用fflush()。

Below is a sample code for using fflush().

#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <io.h>

void flush(FILE *stream);

int main(void)
{
   FILE *stream;
   char msg[] = "This is a test";

   /* create a file */
   stream = fopen("DUMMY.FIL", "w");

   /* write some data to the file */
   fwrite(msg, strlen(msg), 1, stream);

   clrscr();
   printf("Press any key to flush DUMMY.FIL:");
   getch();

   /* flush the data to DUMMY.FIL without closing it */
   flush(stream);

   printf("\nFile was flushed, Press any key to quit:");
   getch();
   return 0;
}

void flush(FILE *stream)
{
     int duphandle;

     /* flush the stream's internal buffer */
     fflush(stream);

     /* make a duplicate file handle */
     duphandle = dup(fileno(stream));

     /* close the duplicate handle to flush the DOS buffer */
     close(duphandle);
}

所有我知道有关fflush()是,它是用来做冲洗输出缓冲器库函数。我想知道是什么),使用fflush的基本宗旨(,在这里我可以用它。主要我有兴趣在明知什么都可以使用fflush的问题()

推荐答案

这是一个有点很难说有什么可以是有问题的(过度?)使用 fflush 的。各种事物的可以的是,或成为,问题,这取决于你的目标和方法。可能是一个更好的方式来看看这是什么意图 fflush

It's a little hard to say what "can be problems with" (excessive?) use of fflush. All kinds of things can be, or become, problems, depending on your goals and approaches. Probably a better way to look at this is what the intent of fflush is.

要考虑的第一件事是, fflush 只定义输出流。输出流收集的东西写入到文件成一个大(ISH)的缓冲区,然后写入该缓冲区的文件。本次征集行动和写作,后来的一点是要提高速度/效率,有两种方式:

The first thing to consider is that fflush is defined only on output streams. An output stream collects "things to write to a file" into a large(ish) buffer, and then writes that buffer to the file. The point of this collecting-up-and-writing-later is to improve speed/efficiency, in two ways:


  • 在现代化的操作系统,有一些惩罚穿越用户/内核保护边界(系统必须改变CPU的一些保护信息等)。如果您有大量的操作系统级别的写调用,你付出的罚款为每一个。如果您收集了起来,说,8192左右个人写成一个大的缓冲区,然后发出一个呼叫,您删除大部分的开销。

  • 在许多现代的操作系统,每个操作系统写的通话将尝试以某种方式,如以优化文件性能,通过发现你已经扩展短文件到一个较长的一个,这将是很好的磁盘块从移动在盘上的点A至点在盘上B,以使较长数据可以适合连续。 (在旧版本的操作系统,这是一个独立的碎片整理步骤中,您可能会手动运行。你可以认为这是现代操作系统做动态,瞬间碎片整理。)如果你写,说,500字节,然后又是200,然后700,等等,它会做很多这项工作的;但如果你有,比如说,8192字节的一大通话,操作系统可以一次分配一个大的块,并把那里的一切,而不必稍后重新整理。

那么,是谁提供你的C库及其标准输入输出流实现的乡亲做什么是您的操作系统适当找到了合理最优的块大小,以及所有输出收集成该大小的块。 (数字4096,8192,16384和65536的时候,今天,往往是好的,但它实际上取决于操作系统上,有时底层文件系统,以及需要注意的是做大并不总是好:同时在流四个千兆字节块数据可能会表现比这样做在64字节块,例如糟糕的。)

So, the folks who provide your C library and its stdio stream implementation do whatever is appropriate on your OS to find a "reasonably optimal" block size, and to collect up all output into chunk of that size. (The numbers 4096, 8192, 16384, and 65536 often, today, tend to be good ones, but it really depends on the OS, and sometimes the underlying file system as well. Note that "bigger" is not always "better": streaming data in chunks of four gigabytes at a time will probably perform worse than doing it in chunks of 64 Kbytes, for instance.)

但是,这造成了一个问题。假设你写一个文件,如日期和时间戳和消息的日志文件,并且你的code是要保持后来写入该文件,但现在,它要暂停一个同时,让一个日志分析仪读取日志文件的当前内容。一种选择是,以添加更多的数据再次使用 FCLOSE 来关闭日志文件,然后的fopen 来打开它后来。它的效率更高,虽然推任何挂起日志消息到底层OS文件,但保留文件打开。这就是 fflush 一样。

But this creates a problem. Suppose you're writing to a file, such as a log file with date-and-time stamps and messages, and your code is going to keep writing to that file later, but right now, it wants to suspend for a while and let a log-analyzer read the current contents of the log file. One option is to use fclose to close the log file, then fopen to open it again in order to append more data later. It's more efficient, though, to push any pending log messages to the underlying OS file, but keep the file open. That's what fflush does.

缓冲也造成了另一个问题。假设你的code的一些bug,而且有时会崩溃,但你不知道它是即将崩溃。并假设你写的东西和这是非常重要的这个的数据走不出来底层文件系统。您可以拨打 fflush 来推动数据到OS,呼唤你的潜在的坏code,它可能会崩溃之前。 (有时候,这是很好的调试。)

Buffering also creates another problem. Suppose your code has some bug, and it sometimes crashes but you're not sure if it's about to crash. And suppose you've written something and it's very important that this data get out to the underlying file system. You can call fflush to push the data through to the OS, before calling your potentially-bad code that might crash. (Sometimes this is good for debugging.)

或者,如果你是一个类Unix系统上,并有一个系统调用。此调用复制整个用户空间(使原工艺的克隆)。标准输入输出缓冲器在用户空间中,所以该克隆具有相同的缓冲式 - 丁还未写入的数据,原始进程有,在叉的时间通话。在这里,解决问题的途径之一就是做之前,使用 fflush 推缓冲的数据出来。如果一切是出了之前,没有什么重复;新鲜克隆永远不会尝试写入缓冲式的数据,因为它已不再存在。

Or, suppose you're on a Unix-like system, and have a fork system call. This call duplicates the entire user-space (makes a clone of the original process). The stdio buffers are in user space, so the clone has the same buffered-up-but-not-yet-written data that the original process had, at the time of the fork call. Here again, one way to solve the problem is to use fflush to push buffered data out just before doing the fork. If everything is out before the fork, there's nothing to duplicate; the fresh clone won't ever attempt to write the buffered-up data, as it no longer exists.

越是 fflush -es添加,更多的你采集打败了大量数据的最初的想法。也就是说,你在做一个权衡:大块的效率更高,但造成了一些其他的问题,所以你做出决定:效率较低这里,解决问题比单纯的效率更重要。你叫 fflush

The more fflush-es you add, the more you're defeating the original idea of collecting up large chunks of data. That is, you are making a tradeoff: large chunks are more efficient, but are causing some other problem, so you make the decision: "be less efficient here, to solve a problem more important than mere efficiency". You call fflush.

有时候问题只是调试软件。在这种情况下,而不是反复调用 fflush ,您可以使用功能,如则setbuf setvbuf用来来改变一个stdio流的缓冲行为。这是更方便(少,甚至没有,code的变化需要,你可以控制一个标志设置缓冲通话),比加入了很多 fflush 的通话,这样可以被认为是问题的使用(或过度使用) fflush

Sometimes the problem is simply "debug the software". In that case, instead of repeatedly calling fflush, you can use functions like setbuf and setvbuf to alter the buffering behavior of a stdio stream. This is more convenient (fewer, or even no, code changes required—you can control the set-buffering call with a flag) than adding a lot of fflush calls, so that could be considered a "problem with use (or excessive-use) of fflush".

这篇关于理解fflush()和问题的与它相关的必要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆