Ios 需要一些关于调度队列、线程和nsrunlop的说明吗

Ios 需要一些关于调度队列、线程和nsrunlop的说明吗,ios,multithreading,grand-central-dispatch,nsthread,nsrunloop,Ios,Multithreading,Grand Central Dispatch,Nsthread,Nsrunloop,以下是我所知道和理解的: 全局队列是一个并发队列,它可以将任务分派给多个线程。无法保证任务的执行顺序。e、 g: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { for (int i; i<10; i++) { doTask() } }) 每次只有一个任务被分派到一个线程&get execute。命令是FIFO ====我感到困惑和不完全理解的内容======== 主线程

以下是我所知道和理解的:

全局队列是一个并发队列,它可以将任务分派给多个线程。无法保证任务的执行顺序。e、 g:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {
 for (int i; i<10; i++) {
  doTask()
 }
})
每次只有一个任务被分派到一个线程&get execute。命令是FIFO

====我感到困惑和不完全理解的内容========

  • 主线程有一个nsrunlop,在主线程中循环任务。我想知道调度队列和运行循环之间的关系是什么? 我是否可以理解为,如果将任务分派到主线程,则主线程的nsrunlop将获取分派的任务并执行它

  • 将任务分派到多个线程的全局队列呢?iOS/OSX系统是否不仅自动创建线程,而且为每个线程创建nsrunlop?然后每个线程中的run循环从全局队列中获取调度的任务并执行它

  • 谁知道线?
    dispatch\u async()
    dispatch\u sync()
    函数是否知道将任务分派到哪个线程,或者队列是否知道将任务分派到哪个线程

  • 是否有方法以编程方式从调度队列获取线程(任务被调度到该线程)的nsrunlop对象?(此问题与问题3有关)

  • 主线程的运行循环和主调度队列之间的关系仅仅是它们都在主线程上运行,并且调度到主队列的块在主线程上与主运行循环上处理的事件交错

    正如政府所说:

    主调度队列是一个全局可用的串行队列,它在应用程序的主线程上执行任务。此队列与应用程序的运行循环(如果存在)一起工作,以将队列任务的执行与附加到运行循环的其他事件源的执行交错。因为它在应用程序的主线程上运行,所以主队列通常用作应用程序的关键同步点

  • 当分派到后台线程时,它不会为这些工作线程创建
    nsrunlop
    。对于这些后台线程,通常也不需要运行循环。我们过去必须为后台线程创建自己的
    nsrunlop
    (例如,在后台线程上调度
    NSURLConnection
    时),但现在不再经常需要这种模式

    对于历史上需要运行循环的事物,如果在后台线程上运行它们,通常会有更好的机制。例如,您现在使用的不是
    NSURLConnection
    ,而是
    nsursession
    。或者,您可以创建GCD计时器调度源,而不是后台线程上的
    nsrunlop
    上的
    NSTimer

  • 关于“知道”线程的人,工作线程在被分派到队列时被标识。线程不是队列的属性,而是在队列需要时分配给队列的

  • 如果要为工作线程创建
    nsrunlop
    (无论如何,通常不应该这样做),可以自己创建并跟踪它。而且,当使用运行循环调度线程时,我倾向于自己创建
    NSThread
    并在该线程上调度运行循环,而不是占用GCD的一个工作线程

  • 主线程的运行循环有一个步骤,在该步骤中它运行在主队列上排队的任何块。如果您想详细了解运行循环的作用,您可能会发现这一点很有用

  • GCD为并发队列创建线程。直到线程上运行的东西第一次请求线程的运行循环时,线程才具有运行循环,此时系统会为线程创建一个运行循环。但是,运行循环仅在该线程上的某个线程要求它运行时运行(通过调用
    -[NSRunLoop run]
    CFRunLoopRun
    或类似命令)。大多数线程,包括为GCD队列创建的线程,从来没有运行循环

  • GCD管理一个线程池,当它需要运行一个块(因为它被添加到某个队列中)时,GCD选择要在其上运行该块的线程。GCD的线程选择算法主要是一个实现细节,除了它总是为添加到主队列的块选择主线程。(请注意,GCD有时还将主线程用于添加到其他队列的块。)

  • 只能获取主线程的运行循环(使用
    +[NSRunLoop mainlunloop]
    CFRunLoopGetMain
    )或当前线程的运行循环(使用
    +[NSRunLoop currentlunloop]
    CFRunLoopGetCurrent
    )。如果需要某个任意线程的运行循环,则必须找到一种方法,在该线程上调用
    CFRunLoopGetCurrent
    ,并以安全、同步的方式跨线程传递其返回值

    请注意,
    nsrunlop
    接口不是线程安全的,但是
    CFRunLoop
    接口是线程安全的,因此如果需要访问另一个线程的运行循环,应该使用
    CFRunLoop
    接口

    还请注意,您可能不应该在GCD队列上运行的块内长时间运行run循环,因为您正在占用GCD希望控制的线程。如果您需要长时间运行一个运行循环,您应该为它启动自己的线程。您可以在中看到这方面的示例。注意它如何使专用线程的运行循环在名为
    sLegacyRL
    的静态变量中可用,该变量在
    dispatch\u信号量\u t
    的保护下初始化


  • 为什么希望/需要在后台线程上运行循环?如果你描述一下你想做什么,我们也许可以
    dispatch_async(dispatch_queue_create("my.serial.queue", nil) {
      ...
    }