【问题标题】:Notification from background thread in C callbackC回调中来自后台线程的通知
【发布时间】:2011-11-19 22:26:00
【问题描述】:

作为我的第一个 Mac 应用程序,我正在构建一个显示传入 MIDI 时间码的应用程序。 因此,我有一个 RtMidi“库”的实例,它包含 MIDI 输入和输出的东西。 Mac OS Core MIDI 回调在空白 C 中,并在内部在多个线程上调用。 C++ 中的 RtMidi 东西,并将这个多线程调用转发到一个(主)线程。

由于我需要一个 Cocoa 函数来通知其他类新的 MIDI 时间码已经到达(大约每 7-9 毫秒发生一次),我实现了一个所有必要类都遵守的单例。

所以,函数的调用顺序是:

    Core MIDI callback -> RtMidi function -> user callback -> Notification ( via Singleton )

基本上,这行得通!

问题是我现在将所有内容都放在同一个线程(主线程)上。如果我从 MIDI 回调中发布通知,并且调用的函数完成时间超过上述 7-9 毫秒,那么核心 MIDI 回调会被阻塞,从而导致整个应用程序冻结。 我尝试调试,似乎发生了某种死锁。

有人对在这种情况下如何实现多线程有一些指导吗? 因为我还在通知观察者中更新 UI,所以我需要所有通知都出现在主线程上。我不明白的是,在这种特殊情况下,C/C++/Objective-C 的一切如何。

【问题讨论】:

    标签: objective-c callback objective-c++ nsnotifications coremidi


    【解决方案1】:

    如果可能的话,我建议您在将调用从后台线程转发到主线程的阶段以非阻塞方式进行。例如,您可以使用performSelectorOnMainThread:withObject:waitUntilDone:,为最后一个参数传递 NO,或其他一些机制,如dispatch_async(dispatch_get_main_queue(), ^{ ... })。这将防止您的后台线程被阻塞,并允许在有时间时更新 UI。

    【讨论】:

    • 感谢您的回答。我尝试了一下,发现只有 GCD 方法,这意味着 dispatch_async(... 实际上在不阻塞应用程序的情况下工作。我试图在dispatch_asyncmechanism 中获得另一个队列以获得尽可能高的优先级。这确实也阻止了该应用程序...有什么想法可以确保立即发布通知吗?提前致谢!
    • 我不确定您所说的“立即”是什么意思;如果你不阻止,除了“尽快”之外,你真的无法得到任何关于时间的保证。
    • 非常感谢。如果一切顺利,我想我将不得不尝试。
    猜你喜欢
    • 1970-01-01
    • 2023-04-05
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    • 2015-10-04
    相关资源
    最近更新 更多