带缓冲区的iostreams的机制是什么?(What's the mechanism of iostreams with buffer?)

编程入门 行业动态 更新时间:2024-10-25 18:35:40
缓冲区的iostreams的机制是什么?(What's the mechanism of iostreams with buffer?)

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

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

有几个条件导致缓冲区被刷新 - 也就是说,要写入实际的输出设备或文件 :程序正常完成,使用诸如endl等操纵器。

在我的理解中,上面的上下文中的句子“操作系统可能将数据存储在缓冲区 (而不是缓冲区中)”意味着流对象和OS都使用它们自己的缓冲区,即进程地址空间中的一个,另一个在OS管理的内核空间中。

这是我的问题,

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

此外,术语' 刷新 '是作用于对象缓冲区还是OS缓冲区?我猜这个刷新的动作实际上引起了系统调用并告诉操作系统立即将数据放入OS缓冲区中。

To start with,Here in cplusplus.com it says every stream object has a associated std::streambuf And in c++ primer 5th it says:

Each output stream manages a buffer, which it uses to hold the data that the programreads and writes. For example, when the following code is executed os << "please enter a value: "; the literal string might be printed immediately, or the operating system might store the data in a buffer to be printed later

There are several conditions that cause the buffer to be flushed—that is, to be written—to the actual output device or file:The program completes normally,using a manipulator such as endl,etc.

In my understanding,the sentence "the operating system might store the data in a buffer(not in the buffer)" in the context above means that both the stream object and OS use their own buffer,that is,one in the process address space,another in the kernel space managed by the OS.

And here is my question,

why does every process/object(like cout) manage its own buffer?Why not just arose a system call and give the data directly to the OS buffer?

Furthermore,is the term 'flushed' acting on object buffer or the OS buffer?I guess the flushed action actually arouse a system call and tell the OS to immediately put the data in OS buffer onto the screen.

最满意答案

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

作为一个预答案,您可以始终重写流缓冲区以始终刷新到系统OS调用以进行输出(或输入)。 实际上,您的系统可能已经这样做 - 它只取决于实现。 这个系统只允许在iostreams库的级别进行缓冲,但并不一定需要它。

对于缓冲,逐字节发送或读取数据并不总是最有效的。 在许多系统中像cout和cin这样的情况下,操作系统可以更好地处理这种情况,但您可以调整iostream来处理读取套接字的输入和输出流(来自Internet连接的I / O)。 在套接字中,您可以通过Internet将单个包中的每个字符写入目标,但这可能会变得非常慢,具体取决于链接类型和链接的繁忙程度。 当您读取套接字时,可以在数据包之间拆分消息,因此您需要缓冲输入,直到达到“临界质量”。 有可能在操作系统级别上执行此缓冲,但我发现至少我可以获得更好的性能,如果我自己处理大部分缓冲(因为通常消息的大小在整个运行时间有很大的标准偏差)。 因此,iostreams中的缓冲是管理输入和输出以优化性能的有用方法,当您尝试同时处理来自多个连接的I / O时,这尤其有用。

但你不能总是假设操作系统会做正确的事情。 我记得有一次我们使用这个FUSE模块,它允许我们在多个计算机节点上拥有一个分布式文件系统。 在编写和阅读单个字符时,它有一个非常奇怪的问题。 虽然读取或写入一长串单个字符在使用ext4系统的普通硬盘上最多需要几秒钟,但同样的操作在FUSE系统上需要几天时间(忽略了我们为什么这样做的原因)。 通过调试,我们发现挂起处于I / O级别,读取和写入单个字符会加剧此运行时问题。 我们不得不重新编写代码来缓冲我们的读写操作。 我们可以弄清楚的最好的是ext4上的操作系统自己做了缓冲,但这个FUSE文件系统在读写硬盘时没有做类似的缓冲。

在任何情况下,OS可以进行自己的缓冲,但是在许多情况下,这种缓冲不存在或最小。 在iostream端缓冲可以帮助您的表现。

此外,术语'刷新'是作用于对象缓冲区还是OS缓冲区?我猜这个刷新的动作实际上引起了系统调用并告诉操作系统立即将数据放入OS缓冲区中。

我相信大多数文本都会谈到C ++中标准I / O流的“刷新”。 您的程序可能无法直接控制操作系统处理其I / O的方式。 但总的来说,我认为操作系统和程序的I / O将与大多数系统同步。

why does every process/object(like cout) manage its own buffer?Why not just arose a system call and give the data directly to the OS buffer?

As a bit of a pre-answer, you could always re-write the stream buffer to always flush to a system OS call for output (or input). In fact, your system may already do this -- it just depends on the implementation. This system just allows buffering at the level of the iostreams library, but doesn't necessarily require it as far as I remember.

For buffering, it is not always the most efficient to send out or read data byte by byte. In cases like cout and cin in many systems this may be better handled by the OS, but you could adapt the iostreams to handle input and output streams that are reading sockets (I/O from internet connections). In sockets, you could write each individual character within a single package to your target over the internet, but this could become really slow depending on the type of link and how busy the link is. When you read a socket, the message can be split across packets so you need to buffer the input until you hit 'critical mass'. There are potentially ways to do this buffering at the level of OS, but I found at least I could get much better performance if I handled most of this buffering myself (since usually the size of messages had a large standard deviation across the runtime). So the buffering within iostreams was a useful way to manage the input and output to optimize performance, and this especially helped when you tried to juggle I/O from multiple connections at the same time.

But you can't always assume the OS will do the right thing. I remember once we were using this FUSE module that allowed us to have a distributed file system across multiple computer nodes. It had a really weird problem when writing and reading single characters. Whereas reading or writing a long sequence of single characters would take at most seconds on a normal hard disk using an ext4 system, the same operation would take days on the FUSE system (ignoring for the moment why we did it this way in the first place). Through debugging, we found the hang was at the level of I/O, and reading and writing individual characters exacerbated this run-time problem. We had to re-write the code to buffer our reads and writes. The best we could figure out is that the OS on ext4 did its own buffering but this FUSE file system didn't do a similar buffering when reading and writing to the hard disk.

In any case, the OS may do its own buffering, but there are a number of cases where this buffering is non-existent or minimal. Buffering on the iostream end could help your performance.

Furthermore,is the term 'flushed' acting on object buffer or the OS buffer?I guess the flushed action actually arouse a system call and tell the OS to immediately put the data in OS buffer onto the screen.

I believe most texts will talk about 'flushed' in terms of the standard I/O streams in C++. Your program probably doesn't have direct control over how the OS handles its I/O. But in general I think the I/O of the OS and your program will be in sync for most systems.

更多推荐

本文发布于:2023-04-29 09:52:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1335878.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:缓冲区   机制   buffer   iostreams   mechanism

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!