• IOS RunLoop理解(参考YYKit)


    RunLoop:概念理解

    一般来讲,一个线程一次只能执行一个任务,执行完成后线程就会退出。如果我们需要一个机制,让线程能随时处理事件但并不退出。

    问题(一):什么是线程,问什么一个线程每次执行一个任务

    首先找资料:

    71.(百度百科)线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有就绪阻塞运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。

    线程是程序中一个单一的顺序控制流程。进程内有一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指令运行时的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为多线程

    2.(维基百科)线程是独立调度和分派的基本单位。线程可以操作系统内核调度的内核线程,如Win32线程;由用户进程自行调度的用户线程,如Linux平台的POSIX Thread;或者由内核与用户进程,如Windows 7的线程,进行混合调度。线程英语:thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。在Unix System VSunOS中也被称为轻量进程(lightweight processes),但轻量进程更多指内核线程(kernel thread),而把用户线程(user thread)称为线程。

    同一进程中的多条线程将共享该进程中的全部系统资源,如虚拟地址空间,文件描述符信号处理等等。但同一进程中的多个线程有各自的调用栈(call stack),自己的寄存器环境(register context),自己的线程本地存储(thread-local storage)。

    一个进程可以有很多线程,每条线程并行执行不同的任务。

    在多核或多CPU,或支持Hyper-threading的CPU上使用多线程程序设计的好处是显而易见,即提高了程序的执行吞吐率。在单CPU单核的计算机上,使用多线程技术,也可以把进程中负责IO处理、人机交互而常被阻塞的部分与密集计算的部分分开来执行,编写专门的workhorse线程执行密集计算,从而提高了程序的执行效率。

    总结:看不懂。越看越不懂。下面决定看c++源码理解线程。

    参考线程博客:paidaxing

    博客园里面找到runloop源码:参考Kenshin Cui's Blog博客(大神真的多)

    int32_t __CFRunLoopRun()
    {
    // 通知即将进入runloop
    __CFRunLoopDoObservers(KCFRunLoopEntry);

    do
    {
    // 通知将要处理timer和source
    __CFRunLoopDoObservers(kCFRunLoopBeforeTimers);
    __CFRunLoopDoObservers(kCFRunLoopBeforeSources);

    // 处理非延迟的主线程调用
    __CFRunLoopDoBlocks();
    // 处理Source0事件
    __CFRunLoopDoSource0();

    if (sourceHandledThisLoop) {
    __CFRunLoopDoBlocks();
    }
    /// 如果有 Source1 (基于port) 处于 ready 状态,直接处理这个 Source1 然后跳转去处理消息。
    if (__Source0DidDispatchPortLastTime) {
    Boolean hasMsg = __CFRunLoopServiceMachPort();
    if (hasMsg) goto handle_msg;
    }

    /// 通知 Observers: RunLoop 的线程即将进入休眠(sleep)。
    if (!sourceHandledThisLoop) {
    __CFRunLoopDoObservers(runloop, currentMode, kCFRunLoopBeforeWaiting);
    }

    // GCD dispatch main queue
    CheckIfExistMessagesInMainDispatchQueue();

    // 即将进入休眠
    __CFRunLoopDoObservers(kCFRunLoopBeforeWaiting);

    // 等待内核mach_msg事件
    mach_port_t wakeUpPort = SleepAndWaitForWakingUpPorts();

    // 等待。。。

    // 从等待中醒来
    __CFRunLoopDoObservers(kCFRunLoopAfterWaiting);

    // 处理因timer的唤醒
    if (wakeUpPort == timerPort)
    __CFRunLoopDoTimers();

    // 处理异步方法唤醒,如dispatch_async
    else if (wakeUpPort == mainDispatchQueuePort)
    __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__()

    // 处理Source1
    else
    __CFRunLoopDoSource1();

    // 再次确保是否有同步的方法需要调用
    __CFRunLoopDoBlocks();

    } while (!stop && !timeout);

    // 通知即将退出runloop
    __CFRunLoopDoObservers(CFRunLoopExit);
    }

  • 相关阅读:
    linux cmake安装方法
    Linux下安装numpy
    linux下安装opencv3.0
    linux升级gcc
    php session获取不到的解决方法
    python Tesseract安装方法
    SQLite-编译指示
    第十章:定积分
    7. 错误、调试和测试
    钱纳里的工业化阶段理论
  • 原文地址:https://www.cnblogs.com/coolcold/p/9100275.html
Copyright © 2020-2023  润新知