- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
以下是我所知道和理解的:
全局队列是一个并发队列,可以将任务分派(dispatch)给多个线程。不保证执行任务的顺序。例如:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), {
for (int i; i<10; i++) {
doTask()
}
})
如果我想分派(dispatch)到串行队列,我可以使用
dispatch_async(dispatch_queue_create("my.serial.queue", nil) {
...
}
每次只有一个任务被分派(dispatch)到一个线程并被执行。顺序是先进先出。
=====我很困惑&不完全理解=======
主线程有一个NSRunLoop,在主线程中循环执行任务。我想知道调度队列和运行循环之间的关系是什么?我可以理解为,如果将任务分派(dispatch)给主线程,主线程的 NSRunLoop 获取分派(dispatch)的任务并执行它吗?
将任务分派(dispatch)给多个线程的全局队列呢? iOS/OSX 系统是否不仅会自动创建线程,还会为每个线程创建 NSRunLoop?然后每个线程中的运行循环从全局队列中获取调度的任务并执行它?
谁知道线程? dispatch_async()
和 dispatch_sync()
函数是否知道将任务分派(dispatch)给哪个线程,或者 queue 是否知道将任务分派(dispatch)给哪个线程?
有没有办法以编程方式从调度队列中获取线程(任务被调度到的线程)的 NSRunLoop 对象? (这个问题与问题3有关)
最佳答案
主线程的运行循环有一个步骤,它运行在主队列中排队的任何 block 。你可能会发现 this answer如果您想详细了解运行循环的作用,这很有用。
GCD 为并发队列创建线程。一个线程没有运行循环,直到线程上运行的东西第一次请求线程的运行循环,此时系统为线程创建一个运行循环。然而,运行循环仅在该线程上的某些东西要求它运行时运行(通过调用 -[NSRunLoop run]
或 CFRunLoopRun
或类似的)。大多数线程,包括为 GCD 队列创建的线程,从来没有运行循环。
GCD 管理一个线程池,当它需要运行一个 block 时(因为它被添加到某个队列),GCD 会选择运行该 block 的线程。 GCD 的线程选择算法主要是一个实现细节,除了它会总是为添加到主队列的 block 选择主线程。 (请注意,GCD 有时也会将主线程用于添加到其他队列的 block 。)
只能获取主线程的run loop(使用+[NSRunLoop mainRunLoop]
或CFRunLoopGetMain
)或者当前线程的run loop(使用 +[NSRunLoop currentRunLoop]
或 CFRunLoopGetCurrent
)。如果您需要某个任意线程的运行循环,您必须找到一种方法在该线程上调用 CFRunLoopGetCurrent
并以安全、同步的方式跨线程传回其返回值。
请注意NSRunLoop
接口(interface)不是线程安全的,但是CFRunLoop
接口(interface)是线程安全的,所以如果你需要访问另一个线程的运行循环,你应该使用CFRunLoop
接口(interface)。
另请注意,您可能不应该在 GCD 队列上运行的 block 内运行运行循环很长时间,因为您正在占用 GCD 期望控制的线程。如果你需要长时间运行一个run loop,你应该为它启动自己的线程。您可以在 the _legacyStreamRunLoop
function in CFStream.c 中看到这样的示例.请注意它如何使专用线程的运行循环在名为 sLegacyRL
的静态变量中可用,它在 dispatch_semaphore_t
的保护下进行初始化。
关于ios - 需要一些关于调度队列、线程和 NSRunLoop 的说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38000727/
我是一名优秀的程序员,十分优秀!