带有缓冲区的iostream的机制是什么?

斯科特肖

首先,在cplusplus.com中,它说每个流对象都有一个关联的std :: streambuf
。在c ++入门5中,它说:

  1. 每个输出流都管理一个缓冲区,它用于保存程序读取和写入的数据。例如,当执行以下代码时,
    os << "please enter a value: ";
    文字字符串可能会立即打印出来,或者操作系统可能会将数据存储在缓冲区中以供以后打印

  2. 有几种情况会导致将缓冲区刷新(也就是写入)到实际的输出设备或文件中:程序使用endl等操纵器正常完成。

在我的理解,这句话“的操作系统可能将数据存储在缓冲区(未在缓冲区)”在上述手段,无论是流对象和操作系统使用自己的缓冲区,也就是一个进程地址空间范围内,由操作系统管理。

这是我的问题,

  1. 为什么每个进程/对象(如cout)都管理自己的缓冲区?为什么不仅仅进行系统调用并将数据直接提供给OS缓冲区?

  2. 此外,术语“刷新”是作用在对象缓冲区还是OS缓冲区上?我猜刷新动作实际上会引起系统调用,并告诉OS立即将OS缓冲区中的数据放到屏幕上。

丹尼尔
  1. 为什么每个进程/对象(例如cout)都管理自己的缓冲区?为什么不仅仅进行系统调用并将数据直接提供给OS缓冲区?

作为先决条件,您始终可以重新编写流缓冲区,以始终刷新到系统OS调用以进行输出(或输入)。实际上,您的系统可能已经这样做了-它仅取决于实现。该系统仅允许在iostreams库级别进行缓冲,但就我所记得的而言并不一定需要它。

对于缓冲,逐字节发送或读取数据并不总是最有效的。在像coutcin在许多系统中,操作系统可能会更好地解决此问题,但是您可以使iostream适应处理正在读取套接字(来自Internet连接的I / O)的输入和输出流。在套接字中,您可以将单个包中的每个字符都通过Internet写入目标,但是根据链接的类型和链接的繁忙程度,这可能会变得很慢。当您读取套接字时,该消息可以拆分为多个包,因此您需要缓冲输入,直到达到“临界质量”为止。有可能在操作系统级别执行此缓冲的方法,但是我发现,如果我自己处理大部分缓冲,至少可以获得更好的性能(因为通常消息的大小在整个运行时中都有很大的标准偏差)。

但是您不能总是假设操作系统会做正确的事。我记得曾经使用过这个FUSE模块,它使我们能够在多个计算机节点上拥有一个分布式文件系统。编写和读取单个字符时,这确实有一个很奇怪的问题。在使用ext4系统的普通硬盘上读取或写入长序列的单个字符最多需要几秒钟,而在FUSE系统上相同的操作则需要几天的时间(暂时忽略了为什么我们首先要这样做) )。通过调试,我们发现挂起处于I / O级别,读写单个字符加剧了此运行时问题。我们必须重新编写代码以缓冲读取和写入。我们能找出的最好的办法是ext4上的操作系统进行了自己的缓冲,但是这个FUSE文件系统没有

在任何情况下,操作系统都可以进行自己的缓冲,但是在许多情况下,这种缓冲不存在或很少。iostream端的缓冲可以帮助您提高性能。

  1. 此外,术语“刷新”是作用在对象缓冲区还是OS缓冲区上?我猜刷新动作实际上会引起系统调用,并告诉OS立即将OS缓冲区中的数据放到屏幕上。

我相信大多数文章都会以C ++中的标准I / O流来谈论“混乱”。您的程序可能无法直接控制操作系统如何处理其I / O。但总的来说,我认为OS和您的程序的I / O对于大多数系统来说都是同步的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章