Runloop深入理解

通常情况下,一个线程执行完一个任务,就会退出并销毁。等到需要处理下一个任务时,又得重新创建一个线程。但是很多时候,这并不是我们想要的结果。例如,

1、当任务小而多时,频繁地创建和销毁线程,会带来不小的代价。

2、iOS/OSX应用的主线程要是退出了,整个应用就挂了。

因此,需要一种能让线程不退出的机制。这种机制就是event loop,event loop在很多语言中都有。Runloop就是它在Objective-C中的实现。

Runloop其实就是个do while循环。它能让线程在没有任务时休眠等待,以避免占用CPU,而有任务需要处理时,又可以及时唤醒。这是怎么做到的呢?需要从Runloop的实现中一探究竟。

Runloop提供了两种API,一种是CoreFoundation中纯C实现的CFRunloopRef;另一种是Foundation中的Objective-C实现的NSRunloop,NSRunloop是对CFRunloopRef的封装。秘密就隐藏在CFRunloopRef的源码中。

void CFRunLoopRun() {
CFRunLoopRunSpecific(CFRunLoopGetCurrent(), kCFRunLoopDefaultMode, 1.0e10, false); }
SInt32 CFRunLoopRunSpecific(CFRunLoopRef rl, CFStringRef modeName, CFTimeInterval seconds, Boolean returnAfterSourceHandled) {    
    __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopEntry); // 1、通知Observer,进入Runloop
    __CFRunLoopRun(rl, currentMode, seconds, returnAfterSourceHandled, previousMode);
    __CFRunLoopDoObservers(rl, currentMode, kCFRunLoopExit); // 10、通知Observer,结束Runloop
} 
static int32_t __CFRunLoopRun(CFRunLoopRef rl, CFRunLoopModeRef rlm, CFTimeInterval seconds, Boolean stopAfterHandle, CFRunLoopModeRef previousMode) {
    int32_t retVal = 0;
    do {
        // Runloop的一次迭代
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeTimers); // 2、通知Observer,即将处理timer
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeSources); // 3、通知Observer,即将处理source
        __CFRunLoopDoBlocks(rl, rlm); // 执行block
        __CFRunLoopDoSources0(rl, rlm, stopAfterHandle); // 处理source0
        __CFRunLoopDoBlocks(rl, rlm); // 执行block
        __CFRunLoopServiceMachPort(dispatchPort, &msg, sizeof(msg_buffer), &livePort, 0)); // 处理source1
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopBeforeWaiting); // 6、通知Observer,即将休眠等待
        __CFRunLoopSetSleeping(rl); // 7、休眠等待
        __CFRunLoopDoObservers(rl, rlm, kCFRunLoopAfterWaiting); // 8、通知Observer,即将被唤醒
        __CFRunLoopDoTimers(rl, rlm, mach_absolute_time()) // 处理timer
        __CFRunLoopDoSource1(rl, rlm, rls, msg, msg->msgh_size, &reply); // 处理source1
        __CFRunLoopDoBlocks(rl, rlm); // 执行block
    } while (0 == retVal);
    return retVal;
}

参考链接:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW23

http://web.mit.edu/darwin/src/modules/xnu/osfmk/man/mach_msg.html

==========================================

mach_msg

MACH_SEND_MSG

MACH_RCV_MSG

猜你喜欢

转载自www.cnblogs.com/yangwenhuan/p/9307368.html