“ funopen”,“ setvbuf”,保证?
funopen
的BSD manpages包括以下文本:
读取和写入I/O功能可以通过调用SETVBUF(3)上的完全缓冲或缓冲流上的底层缓冲区(3)更改基础缓冲区。它们也不需要完全填充或清空缓冲区。但是,他们不允许将流从未夹住到缓冲或更改线条缓冲标志的状态。他们还必须准备好在最近指定的缓冲区上发生阅读或写呼叫。
。
我发现最后一句话非常不足以做出任何实际决定在虚拟文件的整个生命周围。
因为没有关于旧缓冲区可以闲逛或对其进行电话的限制!
i useume 只需要多长时间才能消耗旧缓冲区的数据,但是如果您仅按照书面的方式浏览该文本,这意味着 all> all> ash all buffers 给出setVbuf
可以随时内部重复使用此文件,但无论 都可以在内部重复使用。
现实世界中的期望是什么?什么暗示保证了实际执业的BSD开发人员在行使此功能时知道信任的实际练习?
BSD manpages for funopen
include the following text:
Read and write I/O functions are allowed to change the underlying buffer on fully buffered or line buffered streams by calling setvbuf(3). They are also not required to completely fill or empty the buffer. They are not, however, allowed to change streams from unbuffered to buffered or to change the state of the line buffering flag. They must also be prepared to have read or write calls occur on buffers other than the one most recently specified.
I find that last sentence profoundly insufficient to make any actual decisions, so much so that I'd be uncomfortable with any use of setvbuf
that doesn't just leave all buffers sitting around for the entire lifetime of the virtual file.
Because there's no constraints stated about how long old buffers can hang around or have calls made on them!
I presume it's just for however long it takes for the old buffer's data to be consumed, but if you go by just that text as written, this implies all buffers ever given to setvbuf
for this file can be reused internally at any time, whenever and however the implementation feels like doing.
What's the real-world expectation? What are the implied guarantees that actual practicing BSD developers know to trust when exercising this functionality?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,由于STDIO或
funopen()
api中没有内置的方式,请告诉/何时完全消耗缓冲区的数据funopen2()并提供了flushfn
,该与readfn
和/或writefn
通过与其<其<代码> cookie 参数),实际上“读取和编写i/o函数” 都无法确定他们先前提供的任何缓冲区的何时完全不参考,并且空的。从理论上讲,调用程序可以与主程序的逻辑共享
cookie
,并使用它来引用可以在成功的fflush()
之后设置的标志fread()
或fwrite()
在相关文件>文件> object上(就像
funopen2()
一样可以完成flushfn
' s 但是,练习,至少在本机BSD实现中,
setVbuf()
尝试对电流进行冲洗,并且无论如何都且唯一的缓冲区(尽管没有检查错误,尽管默认的flush函数确实设置了内部错误标志,如果写入失败),如果当前缓冲区是自动/内部分配的,则在分配新提供的缓冲区之前(或分配新的缓冲区)也请注意,请注意使用
setVbuf()
使用null
BUF
参数并期望自动分配它,如果发生内存分配失败,则破坏了不更改缓冲状态的规则。我不确定允许
readfn
和/或writefn
调用setVbuf()
的理由是什么。至少对我来说,这一切似乎都很脆弱和毫无意义。 (代码中的相关注释是“允许交换缓冲” 。)默认功能不利用此津贴。因此,您想从
readfn
或writefn
中调用setVbuf()
的原因是什么功能多次调用setVbuf()
一次(尤其是每次使用不同的(或null
)缓冲区)?Well since there's no built-in in way in STDIO or in the
funopen()
API of telling if/when a buffer's data has been entirely consumed (unless perhaps you're using NetBSD's more recentfunopen2()
and have supplied aflushfn
that communicates withreadfn
and/orwritefn
through some private global object related to theircookie
parameter), there is indeed no way for the "Read and write I/O functions" in and of themselves to determine when any buffers they previously supplied have become wholly unreferenced and empty.In theory a calling program could share the
cookie
with the main program's logic and use it to reference a flag that could be set after a successfulfflush()
and cleared before any newfread()
orfwrite()
on the relatedFILE
object (just as could be done withfunopen2()
'sflushfn
. That way the calling program could share with thereadfn
and/orwritefn
that all data in all buffers had been consumed.In practice though, in native BSD implementations at least,
setvbuf()
tries flushing the current and one and only buffer anyway (albeit without checking for errors, though the default flush function does set the internal error flag if a write fails), and will even free the current buffer if it was automatically/internally allocated before assigning the newly supplied buffer (or allocating a new one if requested).Note also that using
setvbuf()
with aNULL
buf
parameter and expecting it to be automatically allocated may, in the case of a memory allocation failure, break the rule about not changing the buffering state.I'm not sure what the rationale was for allowing
readfn
and/orwritefn
to callsetvbuf()
in the first place. It all seems rather fragile and pointless on first glance, to me at least. (The related comment in the code is "to allow exchange buffering".) The default functions do not make use of this allowance.So, what would your reason be for wanting to call
setvbuf()
from either thereadfn
orwritefn
, and especially why would you consider having either function make a call tosetvbuf()
more than once (and especially with a different (orNULL
) buffer each time)?