【发布时间】:2016-04-03 20:50:07
【问题描述】:
在实现通信协议时,我们有一个编码器,它递归地遍历一些结构并将它们编码成二进制消息。
到目前为止一切都很好,但是现在缓冲区必须分成多个固定大小的块,例如接收缓冲区的上限大小。由于为完整消息分配内存并因此切割它似乎太浪费了(消息的大小是--理论上-- 没有限制),现在的想法是实现一个协程setjmp/longjmp.
目前,我有一个带有两个跳转缓冲区的原型 - 一个用于恢复编码函数的缓冲区,第二个用于模拟函数的返回行为以跳转回其调用者。
嗯,它似乎工作,但代码看起来像是直接来自地狱。是否有任何“约定”来实现可中断的递归函数,可能是一组宏或其他东西?我想只使用标准化函数,而不是内联 asm 以保持便携性。
补充:
原型在这里:https://github.com/open62541/open62541/compare/master...chunking_longjmp
“用法”显示在单元测试内部。
目前,协程行为是为非递归函数Array_encodeBinary 实现的。但是,“协程”行为应扩展到位于此处的通用递归 UA_encodeBinary 函数:https://github.com/open62541/open62541/blob/master/src/ua_types_encoding_binary.c#L1029
【问题讨论】:
-
ISO C 不支持您尝试做的事情。您使用
setjmp和longjmp的方式不受标准的认可,并且在“便携式" C. 你可能会发现setcontext和朋友有点更合适,因为它们实际上是为这个用例设计的,但它们并非在所有平台上都可用,而且使用起来仍然相当尴尬。 -
您可以尝试为协程分配一个单独的堆栈,并使用
setjmp和longjmp在递归协程和它的消费者之间切换。恐怕看不到任何可移植的东西,因为您可能不得不手动摆弄jmpbufs。 -
听起来像是一种臃肿的方法和/或 XY 问题。鉴于这个问题太宽泛了。你的实际问题是什么?使用递归函数——在你写的关于浪费内存的文章中更是如此(那是嵌入式系统吗?)——大多数时候是个坏主意。
-
您能发布您现有的代码吗?无意冒犯,但这听起来像是一个可怕的黑客攻击 [使用
setjmp/longjmp]。我以前做过这种事情,我可以想出很多方法来做到这一点,这些方法很干净,但是有一些上下文可以帮助理解。 -
“二进制massage”现在听起来很放松,但我认为这是关于“二进制消息”。 :-)
标签: c recursion coroutine setjmp