CycloneDDS中dds_waitset_wait未阻塞直接返回0的问题咨询
我仔细看了你的问题描述——用CycloneDDS v0.11.0的waitset搭配读条件,明明设了DDS_INFINITY超时,结果dds_waitset_wait直接返回0(超时),完全没按预期阻塞,这确实挺让人困惑的。结合你给出的代码和CycloneDDS的特性,我整理了几个可能的原因和排查方向:
一、读条件在初始化时就已经满足触发状态
这是最常见的原因:当你创建读条件并附加到waitset时,reader里可能已经存在未被读取的存活实例数据了,这时候读条件的触发值一开始就是true,所以dds_waitset_wait会立刻返回,不会阻塞。
你可以做这两步验证和处理:
- 在调用
dds_waitset_wait之前,先调用dds_take或者dds_read把reader中所有未读的数据清空,确保初始状态下没有符合读条件的数据; - 可以用
dds_readcondition_get_trigger_value(rdcond)检查读条件的当前状态,如果返回true,就说明初始条件已经满足,这时候wait自然不会阻塞。
二、未检查读条件和waitset附加的返回值
你给出的代码里没有检查dds_create_readcondition和dds_waitset_attach的返回结果,如果这两个步骤中有一个失败(比如reader无效、参数错误),那么waitset的行为就会异常,可能出现直接返回0的情况。
建议在代码中加上错误检查:
auto rdcond = dds_create_readcondition(reader, DDS_ALIVE_INSTANCE_STATE | DDS_NOT_READ_SAMPLE_STATE); if (rdcond == NULL) { // 处理读条件创建失败的情况,比如打印错误日志 fprintf(stderr, "Failed to create read condition\n"); return; } int attach_status = dds_waitset_attach(waitSet, rdcond, reader); if (attach_status != DDS_RETCODE_OK) { fprintf(stderr, "Failed to attach read condition to waitset, code: %d\n", attach_status); dds_delete(rdcond); return; }
三、CycloneDDS v0.11.0的已知bug
v0.11.0是一个比较旧的版本(发布于2020年左右),后续的CycloneDDS版本修复了不少waitset相关的问题,比如超时处理逻辑、读条件触发判断的bug。你可以尝试升级到较新的稳定版本(比如v0.12.x或者v0.13.x),看看问题是否消失。
四、读条件的状态组合可能存在逻辑问题
你使用的状态组合是DDS_ALIVE_INSTANCE_STATE | DDS_NOT_READ_SAMPLE_STATE,有没有可能存在一些你没注意到的场景满足这个条件?比如:
- 已经存在一个存活的实例,但你从未读取过它的数据;
- 实例的状态在创建读条件后被更新,但你没感知到。
可以尝试简化读条件的状态,比如先只使用DDS_NOT_READ_SAMPLE_STATE,看看wait是否能正常阻塞,逐步排查是不是状态组合的问题。
备注:内容来源于stack exchange,提问作者mehmetfa

