Asynchronous 如何在Boost Spirit中使用非阻塞或异步IO?

Asynchronous 如何在Boost Spirit中使用非阻塞或异步IO?,asynchronous,nonblocking,boost-spirit,Asynchronous,Nonblocking,Boost Spirit,Spirit是否提供使用非阻塞IO的任何功能 提供一个更具体的例子:我想使用Boost的Spirit解析框架来解析来自非阻塞模式下的网络套接字的数据。如果数据不完全可用,我希望能够使用该线程执行其他工作,而不是阻塞 简单的答案是在调用Spirit之前读取所有数据,但可能需要从套接字接收和解析千兆字节的数据 似乎为了在解析时支持非阻塞I/O,Spirit需要一些能力来部分解析数据,并且能够在没有更多数据可用时暂停并保存其解析状态。此外,当数据变得可用时,它需要能够从保存的解析状态恢复解析。或者我把

Spirit是否提供使用非阻塞IO的任何功能

提供一个更具体的例子:我想使用Boost的Spirit解析框架来解析来自非阻塞模式下的网络套接字的数据。如果数据不完全可用,我希望能够使用该线程执行其他工作,而不是阻塞

简单的答案是在调用Spirit之前读取所有数据,但可能需要从套接字接收和解析千兆字节的数据

似乎为了在解析时支持非阻塞I/O,Spirit需要一些能力来部分解析数据,并且能够在没有更多数据可用时暂停并保存其解析状态。此外,当数据变得可用时,它需要能够从保存的解析状态恢复解析。或者我把这个问题弄得太复杂了?

TODO将发布一个简单的单线程“基于事件”的解析模型示例。这在很大程度上是微不足道的,但可能正是您所需要的

对于任何不那么琐碎的事情,请注意以下注意事项/提示/提示:


您将如何使用结果?无论如何,您不会更早地拥有合成属性,或者您打算动态使用语义操作吗

由于回溯,这种方法通常效果不佳。注意事项可以通过谨慎和明智地使用qi::hold、qi::LOCAL以及在永远不会被回溯的电台上只使用具有副作用的语义动作来解决。换言之:

  • 这肯定是非常容易出错的
  • 这自然只适用于有限的一组语法(那些具有丰富上下文信息的语法不适合这种处理)
当然,现在一切都是被迫的,但总的来说,经验丰富的程序员应该学会避免逆流而上

现在,如果您还想这样做:

通过定义BOOST_spirit_THREADSAFE并链接到libboost_线程,您应该能够获得spirit库线程安全/可重入注意这使得Spirit threadsafe使用的gobals是安全的(以细粒度锁定为代价),而不是您的解析器:您不能跨线程共享自己的解析器/规则/子语法/表达式。事实上,您只能共享您自己的(Phoenix/Fusion)functor(如果它们是线程安全的),并且应该审核在核心Spirit库之外定义的任何其他扩展的线程安全性

如果你能做到这一点,我认为目前为止最好的方法似乎是

  • 使用boost::spirit::istream_迭代器(或者,对于二进制/原始字符流,我更愿意使用
    boost::spirit::istreambuf_迭代器
    使用
    boost::spirit::multi_pass
    模板类)来使用输入。请注意,根据您的语法,相当多的内存可用于缓冲,并且性能不理想
  • 在自己的线程上运行解析器(或逻辑线程,例如Boost Asio“threads”或其著名的“stackless coprocedures”)
  • 使用如上所示的粗粒度语义操作将消息传递给另一个执行实际处理的逻辑线程
一些更松散的指针:

  • 您可以使用BOOST_FUSION_ADAPT_函数和friends轻松地“融合”一些函数来处理语义动作处理程序的惰性评估;这减少了编写的CRUFT的数量,以使简单的事情像语义上的普通C++过载解决方案一样工作——尤其是当您不使用C++ 0x和BooStReultTyfOy UsjyDeCype < /LI>时
  • 因为您希望避免产生副作用的语义操作,所以您可能应该查看继承属性和
    qi::locals
    ,以“纯功能方式”跨规则协调状态

谢谢!我期待着看到你的榜样。我很高兴你强调了一些与回溯相关的要点。我正在研究的一个语法中有很多期望点,所以我没问题,但对于其他语法来说,我知道这一点是很好的。至于我将如何使用结果,我还没有达到这一点,但这确实是我自己的问题。我打算深入研究语义操作和/或属性兼容性规则,以确定是否有某种方法可以在达到预期点后“流式”输出属性。@Emanuel:erm。不,关于使用结果的问题定义了流媒体是否有意义。在不必要地使解析器步骤复杂化之前,您应该有一个这样的设计/模型,非常感谢。有许多操作根本无法流式处理(想想XSLT转换,或者简单的反向过滤器——你无法打败熵,即使你非常努力地尝试多线程和消息队列。你只会得到大量锁定线程或长队列)。因为永远不兑现承诺不是好的风格,关于单线程和多线程基于事件的解析器设计,我参考了最近的示例: