zoukankan      html  css  js  c++  java
  • 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);
    }

  • 相关阅读:
    ini_set /ini_get函数功能-----PHP
    【转】那个什么都懂的家伙
    word 2007为不同页插入不同页眉页脚
    August 26th 2017 Week 34th Saturday
    【2017-11-08】Linux与openCV:opencv版本查看及库文件位置等
    August 25th 2017 Week 34th Friday
    August 24th 2017 Week 34th Thursday
    August 23rd 2017 Week 34th Wednesday
    August 22nd 2017 Week 34th Tuesday
    August 21st 2017 Week 34th Monday
  • 原文地址:https://www.cnblogs.com/coolcold/p/9100275.html
Copyright © 2011-2022 走看看