具有共享streambuf的istream和ostream相互线程安全以进行双工I/O吗? [英] istream and ostream with shared streambuf mutually thread-safe for duplex I/O?

查看:54
本文介绍了具有共享streambuf的istream和ostream相互线程安全以进行双工I/O吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为缓冲的网络套接字I/O派生了一个自定义的streambuf,覆盖了下溢,溢出和同步,以便下溢与其他两个缓冲区的设置是相互线程安全的,(我有单独的输入和输出内部缓冲区).效果很好,但是我想将其用于全双工I/O,其中一个线程可以输入,而另一个线程正在输出,因此我想在共享网络的同时使用istream作为接收线程,使用ostream作为发送线程.streambuf,因为它抽象了所有套接字的东西.我的问题是,如果输入和输出缓冲区分开,那么受istream上输入操作影响的streambuf成员与受ostream上输出操作影响的streambuf成员在何种程度上不相交?

I've derived a custom streambuf for buffered network socket I/O, overriding underflow, overflow, and sync so that underflow is mutually thread-safe with the set of the other two, (I have separate input and output internal buffers). That works fine, but I want to use this for full duplex I/O where one thread can input while another is outputting, so I'd like to use an istream for the receiving thread and ostream for the sending one, while sharing the network streambuf as that abstracts all the socket stuff. My question is, to what extent are the streambuf members affected by input operations on an istream disjoint from the streambuf members affected by output operations on an ostream if the input and output buffers are separate?

能够做到这一点比将套接字内容从我的streambuf抽象中分离出来更好,这样套接字就可以在istream和ostream之间通过单独的streambufs进行共享了,那么我还需要两个版本的streambuf –一个带有一个内部缓冲区(仅用于istream或仅用于ostream),一个带有两个内部缓冲区(如我现在使用的),用于iostream ...很烂,因为这是附加的类和代码重复.>

It would be better to be able to do that rather than have to separate the socket stuff from my streambuf abstraction so the socket can be shared between istream and ostream with separate streambufs--then I'd also need two versions of the streambuf--one with a single internal buffer (for use in either istream only or ostream only), and one with two internal buffers as I have now, for use in iostream... sucks as that's additional classes and code duplication.

推荐答案

对于 std :: streambuf (或 std :: basic_streambuf< ...>)比通常提供的保证更多.也就是说,您可以有多个线程随时读取对象的状态,但是如果有一个线程修改了对象的状态,那么将不会有其他线程访问该对象.读写字符都会修改流缓冲区的状态,即从正式的角度来看,没有外部同步就无法使用它们.

There is no special guarantee given for std::streambuf (or std::basic_streambuf<...>) which gives more guarantees than what is generally given. That is, you can have multiple threads reading the object's state at any time but if there is one thread modifying the object's state there shall be no other thread accessing the object. Both reading and writing characters modify the stream buffer's state, i.e. from a formal point of view you can't use them without external synchronization.

在内部,两个缓冲区是完全分开的,并且彼此无关.流缓冲区上的操作以一种相当结构化的方式对其进行了修改,我无法想象任何实现都会在两组指针之间进行显式交互.也就是说,实际上,我认为读写之间不需要任何同步.但是,我之前从未意识到两组缓冲区指针实际上可能共享相同的缓存行,这至少会导致性能问题.我认为这不会引起任何正确性问题.

Internally the two buffers are entirely separate and have nothing to do with each other. The operations on stream buffers modify them in a rather structured way and I can't imagine that any implementation would have an explicit interaction between the two sets of pointers. That is, in practical terms I don't think there is any synchronization necessary between reading and writing. However, I hadn't realized before that the two sets of buffer pointers may actually share the same cache lines which may at least cause performance problems. I don't think this should cause any correctness problems.

两个流缓冲区之间唯一可能共享的资源是 std :: locale 对象,但这意味着该对象是无状态的.另外, std :: streambuf 本身没有使用任何对象:它是您的流缓冲区,可能使用某些方面(例如, std :: codecvt< ...> 方面).当通过调用虚拟函数 imbue()更改语言环境时,如果流缓冲区使用该语言环境,您将能够拦截此更改并执行所需的任何同步.

The only resource possibly shared between the two stream buffers is the std::locale object which is meant to be stateless, however. Also, std::streambuf doesn't make any use of this object itself: it is your stream buffer which may use some of the facets (e.g. the std::codecvt<...> facet). As the locale is changed via a call to the virtual function imbue() you would be able to intercept this change and do whatever synchronization is needed if your stream buffer uses the locale.

总而言之,该标准并不能保证它可以使用并发线程使用相同的流缓冲区进行读写.实际上,DS9k可能是唯一会发生故障的系统,并且由于缓冲区指针最终位于共享缓存行中,两个线程可能最终有效地同步.

In summary, the standard doesn't make any guarantee that it would work to use concurrent threads to read and write using the same stream buffer. In practice, the DS9k is probably the only system where it would fail and the two threads may end up effectively synchronized due to the buffer pointers ending up in shared cache lines.

这篇关于具有共享streambuf的istream和ostream相互线程安全以进行双工I/O吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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