Sam*_*ott 5 c++ ssl multithreading boost
TLDR:Strands序列化在完成处理程序之间共享的资源:如何防止ssl :: stream实现对并发读写请求(stream :: ssl不是全双工)对SSL上下文(内部使用)的并发访问?请记住,strand仅序列化完成处理程序调用或读/写请求的原始队列。[感谢sehe帮助我更好地表达了这一点]
我花了整整一天的时间阅读有关ASIO,SSL和链的信息;主要在stackoverflow上(其中有一些非常详细且表达明确的解释,例如,为什么在使用boost :: asio时为什么需要每个连接使用绞链)和Boost文档;但有一点尚不清楚。
显然,链可以序列化同一链中的回调,因此也可以序列化对那些链共享的资源的访问。
但是在我看来,boost :: asio :: ssl :: stream的问题不在完成处理程序回调中,因为不是在SSL上下文上同时运行的回调,而是ssl :: stream的实现。 。
我不能确定在调用async_read_some和async_write_some时使用strands或在完成处理程序中使用strands会阻止io引擎同时在不同线程中的SSL上下文上运行。
显然,在调用async_read_some或async_write_some时使用绞合线将意味着不能同时在同一队列中进行读取和写入,但是我看不到如何阻止内部实现同时在不同的位置执行读取和写入操作如果封装的tcp :: socket同时准备好进行读取和写入,则将线程化。
在此问题的最后一个答案末尾的注释增强了asio-来自一个线程的SSL async_read和async_write声称并发写入ssl :: stream可能会出现段错误,而不仅仅是交错,这表明该实现未采取必要的锁定措施来防范并发访问。
除非实际的延迟套接字写操作绑定到将其排队的线程/线程(我看不到它是正确的,否则会破坏工作线程的有用性),否则我如何确定可以将读取排队并在同一ssl :: stream上进行写入,或者那样的方式可能是?
也许async_write_some立即使用SSL上下文处理所有数据,以生成加密数据,然后成为普通套接字写入,因此可以与同一链上的读取完成处理程序不冲突,但这并不意味着在完成处理程序在链上排队之前,它不会与内部实现套接字读取和解密冲突。不必介意可能发生的透明SSL会话重新协商...
我从中注意到:为什么在使用boost :: asio时为什么每个连接都需要链?“组合操作是唯一的,因为对流的中间调用是在处理程序的链中(如果存在的话)而不是在其中发起组合操作的链中调用。” 但是我不确定我指的是“流的中间调用”。这是否意味着:“该流实现中的任何后续处理”?我怀疑不是
最后,为什么,为什么?为什么ssl :: stream实现不使用没有冲突的廉价futex或其他锁?如果遵循绞线规则(隐式或显式),则成本几乎不存在,但否则将提供安全性。我问,因为我刚刚将Sutter,Stroustrup和其他产品的宣传转移了,C ++使一切变得更好,更安全,因此使用ssl :: stream似乎很容易遵循某些咒语,但几乎无法知道您的代码是否真正安全。
问: 但我不确定我指的是“对流的中间调用”。这是否意味着:“该流实现中的任何后续处理”?我怀疑不是
文档说明了这一点:
此操作是通过零次或多次调用流的 async_read_some 函数来实现的,称为组合操作。程序必须确保流在此操作完成之前不执行其他读取操作(例如 async_read、流的 async_read_some 函数或执行读取的任何其他组合操作)。文档
最后,为什么,为什么,为什么 ssl::stream 实现不使用 futex 或其他在没有冲突时便宜的锁?
您不能跨异步操作持有 futex,因为任何线程都可能执行完成处理程序。所以,你仍然需要这里的链,使 futex 变得多余。
这个问题的最后一个答案末尾的评论增强了 asio - SSL
async_read
并async_write
来自一个线程,声称并发写入可能会ssl::stream
出现段错误而不仅仅是交错,这表明该实现没有采取必要的锁来防止并发访问。
请参阅之前的条目。不要忘记多个服务线程。数据竞争是未定义的行为
长话短说:异步编程是不同的。这是有充分理由不同的。不过,你必须调整你的思维来适应它。
链通过抽象异步调度程序上的顺序执行来帮助实现。
这使得您不必知道调度是什么、正在运行多少个服务线程等。
归档时间: |
|
查看次数: |
620 次 |
最近记录: |