作为我的第一个 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 是如何进行的。
最佳答案
我建议在将调用从后台线程转发到主线程的阶段,如果可能的话,以非阻塞方式进行。例如,您可以使用 performSelectorOnMainThread:withObject:waitUntilDone:
,为最后一个参数传递 NO,或使用一些其他机制,如 dispatch_async(dispatch_get_main_queue(), ^{ ... })
。这将防止您的后台线程被阻塞,并允许在有时间时更新 UI。
关于objective-c - 来自 C 回调中后台线程的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8197852/