gpt4 book ai didi

c++ - RPi2、OpenMAX、死锁

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:48:15 24 4
gpt4 key购买 nike

环境

  • 树莓派 2 B+
  • Debian Linux
  • OpenMAX 语言

用例

  • OpenMAX 相机视频捕捉
    • 相机端口已禁用
    • 设置渲染器/相机隧道
    • 所有组件状态都设置为空闲
    • 端口已启用

问题描述

第一个端口被启用到相机输入端口(端口#73),该端口正在使用“OMX_CommandPortEnable”命令启用,与“OMX_CommandPortDisable”命令一样,相机组件预计会触发它的“OMX_CALLBACKTYPE::EventHandler”事件处理程序具有“eEvent == OMX_EventCmdComplete”和“nData1 == OMX_CommandPortEnable”,但是,这从未发生,应用程序无限等待端口启用。

问题分析

我将 std::condition_variable 与 std::mutex 结合使用以等待状态更改完成,因此,OMX_CALLBACKTYPE::EventHandler 更新条件变量并调用“notify_one()”,同时调用线程锁定 std: :mutex 并等待条件变量被设置,使用这种方法“OMX_CALLBACKTYPE::EventHandler”永远不会被调用(带有任何参数),并且程序永远锁定。
注意:当等待条件变量时,互斥锁被验证为不被拥有,这是通过验证 (0 == std::mutex::__owner) 来完成的。
但是,通过迭代调用 usleep 和 OMX_GetParameter(OMX_IndexParamPortDefinition) 轮询端口状态时一切正常。

手头的问题

为什么“OMX_CALLBACKTYPE::EventHandler”在轮询它的值时触发,而在使用条件变量时不触发?在 Windows 中有 APC 和可警告线程的概念,在 Linux 中是否有任何等价物?有没有人能解释上面提到的?

最佳答案

我的经验是,启用端口不会发出事件回调,直到端口填充了缓冲区。即顺序为:

  • 将端口设置为启用(OMX_SendCommand()OMX_CommandPortEnable)。
  • 填充端口缓冲区(OMX_AllocateBuffer()OMX_UseBuffer())。
  • 接收OMX_CommandPortEnable事件回调。

如果在分配缓冲区之前等待事件回调,那么就会出现死锁。

当您通过测试 OMX_PARAM_PORTDEFINITIONTYPE.bEnabled 进行轮询时,将立即返回 OMX_TRUE,因为 the spec说这个成员是同步设置的:

The port shall immediately set bEnabled in its port definition structure when the port receives OMX_CommandPortEnable.

这是我认为当事情“有效”时你会发生的事情:

  • 将端口设置为启用。
  • 轮询直到 bEnabledOMX_TRUE(立即发生)。
  • 填充端口缓冲区。
  • 接收OMX_CommandPortEnable事件回调。

您可能会错误地认为它是按以下顺序发生的:

  • 将端口设置为启用。
  • 轮询直到 bEnabledOMX_TRUE(立即发生)。
  • 接收OMX_CommandPortEnable事件回调。
  • 填充端口缓冲区。

这使得使用条件变量似乎以某种方式改变了 OpenMAX 行为。实际上,bEnabledOMX_CommandPortEnable 回调并不是真正报告同一件事。我认为在启用端口和分配其缓冲区之间不需要(或不需要)任何同步。

关于c++ - RPi2、OpenMAX、死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34545625/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com