multithreading - CoreFoundation : Receive/process notifications in background thread

标签 multithreading macos background notifications runloop

我正在编写一个简单的应用程序,该应用程序应该能够使用Apple的CoreFoundation框架在后台线程中接收和处理通知。这是我要完成的工作:

static void DummyCallback(CFNotificationCenterRef center,
              void *observer,
              CFStringRef name,
              const void *object,
              CFDictionaryRef userInfo) {
    printf("RECEIVED NOTIFICATION\n");
}

void *ThreadStart(void *arg) {
    CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
                    NULL, 
                    &DummyCallback, 
                    NULL,
                    CFSTR("TEST_OBJECT"),
                    CFNotificationSuspensionBehaviorDeliverImmediately);

    printf("background thread: run run loop (should take 5 sec to exit)\n");
    int retval = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, true);
    printf("background thread: exited from run loop (retval: %d)\n", retval);
    return NULL;
}

int main(int argc, char** argv) {
    pthread_t thread;
    int rc = pthread_create(&thread, NULL, &ThreadStart, NULL);
    assert(rc == 0);

    printf("main: sleep\n");
    sleep(10);
    printf("main: done sleeping\n");

    return 0;
}

如果我运行程序,我会得到
main: sleep
background thread: run run loop (should take 5 sec to exit)
background thread: exited from run loop (retval: 1)
main: done sleeping

问题在于后台线程的运行循环立即退出(返回代码kCFRunLoopRunFinished而不是kCFRunLoopRunTimedOut),因为没有源/观察者/计时器。 CFNotificationCenterAddObserver仅在主线程的运行循环中注册自己,而在我的后台线程之一中注册。

我需要其他一些东西的主线程,并且不能使用它来运行它的运行循环。有什么办法可以使它正常工作吗?也许通过向后台线程的运行循环注册CFNotificationCenter?

提前致谢!

最佳答案

http://developer.apple.com/library/mac/#documentation/CoreFoundation/Reference/CFNotificationCenterRef/Reference/reference.html中所述

观察者首次在分布式通知中心注册时,通知中心将与系统范围的通知服务器建立连接,并将监听端口置于当前线程运行循环的常见模式下。传递通知后,即使在其他线程上为该通知注册了接收通知的观察者,也会在此初始线程上对其进行处理。

因为加载的框架可能会在代码执行之前生成线程并添加其自己的观察者,所以您无法确定哪个线程将接收分布式通知。如果需要控制哪个线程处理通知,则回调函数必须能够将通知转发到适当的线程。您可以使用CFMessagePort对象或自定义CFRunLoopSource对象将通知发送到正确的线程的运行循环。

关于multithreading - CoreFoundation : Receive/process notifications in background thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6589337/

相关文章:

css - 视频作为背景

c# - 模拟页面生命周期从UI层抓取html

c++ - 休眠/重启线程

arrays - 读取文本文件时如何忽略标题

ios - 信标范围在后台

android - 如何创建一个点击后闪烁的按钮?

c# - Threading.SpinWait 结构与 Thread.SpinWait 方法

c++ - 如何在 Poco 中设置在内核跟踪/ps/gdb 中调试可见的单个线程名称?

javascript - 捕捉 Mac 触控板缩放

c++ - mbtowc 在 osx 上始终返回一个字节