【问题标题】:IOS semaphore_wait_trap on main thread causing hang in UI主线程上的 IOS semaphore_wait_trap 导致 UI 挂起
【发布时间】:2012-11-08 12:49:53
【问题描述】:

我在异步(串行)工作队列中有一个长时间运行的函数。 我知道有时这个函数会挂在特定的 openCV 调用中。 由于某种原因,这种挂起也会导致主线程挂起。 暂停并进入调试模式时,我看到有人调用

semaphore_wait_trap()

在主线程(队列)上

我可以在调试模式下挂起挂起的线程(我的工作队列),然后这个陷阱消失,GUI 再次在手机上响应。

取消暂停工作线程后,GUI 会响应 1-2 秒(我怀疑直到再次激活该线程),然后 UI 再次变得无响应。

此线程不对主线程/队列进行dispatch_sync() 调用

IOS 是否有可能因为 worker 长时间运行而暂停主线程(“陷阱”它)?

我可以强制它删除块吗??

我正在添加调试模式堆栈的一些打印屏幕。

在挂起队列之前:

还有挂线:

在暂停和挂起坏队列之后:

【问题讨论】:

  • “pixtr”是您还是第三方产品? .如果是第三方,我会考虑将其从您的 UI 中分离出来,看看是否是问题
  • 这里没有什么可做的(特别是,我不知道add_blob 中的内容),所以我最好的就是猜测。我怀疑您将错误的标志传递给cvFloodFill,这会导致它挂起锁定GPU。由于 UIKit 还需要 GPU 来计算滚动(DYTransport 是与 GPU 计算相关的私有框架),这会挂起 UIKit 等待 GPU 可用。

标签: ios semaphore freeze


【解决方案1】:

IOS 是否有可能因为 worker 长时间运行而暂停主线程(“陷阱”它)? - 不。 我认为,您的问题与绘制或更改某些 UI 元素有关。并非所有函数都可以从后台线程调用(例如,UI 元素的更改必须在主线程中完成。)。在您的串行队列中,如果任何方法需要更改 UI 元素,您必须在主线程上调用它,例如

dispatch_async(dispatch_get_main_queue(), ^{
                //do some main thread job here
            });
)

【讨论】:

  • 我正在做 dispatch_queue_create("worker_queue", DISPATCH_QUEUE_SERIAL);
  • dispatch_async(my_queue, {worker block with callback on completion })
  • 我在工作线程上使用 GPU。那可以挂主线程吗?如果是这样怎么做?
  • 我和您一样使用过 OpenCV,但遇到了您所面临的问题。就我而言,问题在于我在后台线程上使用了 Core Graphics 函数。您必须提供调度块代码,以及您在块中调用的方法的代码,以便我们为您提供帮助。
  • @FahriAzimov 你知道检测哪一行代码导致它的方法吗?也许是信号量的符号断点?
【解决方案2】:

也许您只是忘记在调度函数调用中保留一个变量(对我来说,在 dispatch_once_t 声明之前我省略了一个静态关键字,并且调度无法使用内联函数处理)。堆栈跟踪就像你的一样。那是我的错。

+ (instancetype)sharedInstance
{
    (static was omitted) dispatch_once_t once;
    static id sharedInstance;
    dispatch_once(&once, ^{
        sharedInstance = [[self alloc] init];
    });
    return sharedInstance;
} 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多