01. Dispatch
Execute code concurrently on multicore hardware by submitting work to dispatch queues managed by the system.
- 通过提交工作来调度系统管理的队列,在多核硬件上同时执行代码。
Overview
Dispatch comprises language features, runtime libraries, and system enhancements that provide systemic, comprehensive improvements to the support for concurrent code execution on multicore hardware in macOS, iOS, watchOS, and tvOS.
- Dispatch包括语言功能,运行时库和系统增强功能,可为macOS,iOS,watchOS和tvOS中多核硬件上的并发代码执行提供系统,全面的改进。
The BSD subsystem, Core Foundation, and Cocoa APIs have all been extended to use these enhancements to help both the system and your application to run faster, more efficiently, and with improved responsiveness. Consider how difficult it is for a single application to use multiple cores effectively, let alone doing it on different computers with different numbers of computing cores or in an environment with multiple applications competing for those cores. GCD, operating at the system level, can better accommodate the needs of all running applications, matching them to the available system resources in a balanced fashion.
- BSD子系统,Core Foundation和Cocoa API都已扩展为使用这些增强功能,以帮助系统和应用程序更快,更高效地运行,并提高响应速度。 考虑单个应用程序有效使用多个内核的难度,更不用说在具有不同数量的计算内核的不同计算机上或在多个应用程序竞争这些内核的环境中执行此操作。 在系统级别运行的GCD可以更好地满足所有正在运行的应用程序的需求,并以平衡的方式将它们与可用的系统资源相匹配。
Managing Dispatch Queues
GCD provides and manages FIFO queues to which your application can submit tasks in the form of block objects. Work submitted to dispatch queues are executed on a pool of threads fully managed by the system. No guarantee is made as to the thread on which a task executes.
- GCD提供并管理应用程序可以以块对象的形式提交任务的FIFO队列。 提交到调度队列的工作在完全由系统管理的线程池上执行。 不保证任务执行的线程。
Synchronous and Asynchronous Execution
- 同步和异步执行
Each work item can be executed either synchronously or asynchronously. When a work item is executed synchronously with the sync method, the program waits until execution finishes before the method call returns. When a work item is executed asynchronously with the async method, the method call returns immediately.
- 每个工作项可以同步或异步执行。 当一个工作项用sync方法同步执行时,在方法调用返回之前,程序将会等待,直到工作项执行完成。 当工作项使用async异步方法异步执行时,方法调用立即返回。
Serial and Concurrent Queues
- 串行和并发队列
A dispatch queue can be either serial, so that work items are executed one at a time, or it can be concurrent, so that work items are dequeued in order, but run all at once and can finish in any order. Both serial and concurrent queues process work items in first in, first-out (FIFO) order.
- 调度队列可以是串行的,因此工作项可以一次执行一个,也可以是并发的,因此工作项按顺序出列,但可以一次性运行,并且可以按任何顺序完成。 串行和并发队列都以先进先出(FIFO)顺序处理工作项。
System-Provided Queues
- 系统提供的队列
When an app launches, the system automatically creates a special queue called the main queue. Work items enqueued to the main queue execute serially on your app’s main thread. You can access the main queue using the main type property.
- 当应用程序启动时,系统会自动创建一个名为主队列的特殊队列。 排队到主队列的工作项在应用程序的主线程上串行执行。 您可以使用main type属性访问主队列。
Important
Attempting to synchronously execute a work item on the main queue results in dead-lock.
- 尝试在主队列上同步执行工作项会导致死锁。
In addition to the serial main queue, the system also creates a number of global concurrent dispatch queues. You can access the global concurrent queue that best matches a specified quality of service (QoS) using the global(attributes:) type method.
- 除串行主队列外,系统还会创建许多全局并发调度队列。 您可以使用global(attributes :)类型方法访问与指定服务质量(QoS)最匹配的全局并发队列。
DispatchQueue manages the execution of work items. Each work item submitted to a queue is processed on a pool of threads managed by the system.
- DispatchQueue管理工作项的执行。 提交到队列的每个工作项都在系统管理的线程池上处理。
DispatchSpecificKey
is a class that encapsulates keys that can be associated with a contextual value on a DispatchQueue
using the setSpecific<T>(key:value:) method, and accessed using the getSpecific<T>(key:) method.
- DispatchSpecificKey是一个类,它使用setSpecific <T>(key:value :)方法封装可以与DispatchQueue上的上下文值相关联的键,并使用getSpecific <T>(key :)方法进行访问。
Managing Units of Work
Work items allow you to configure properties of individual units of work directly. They also allow you to address individual work units for the purposes of waiting for their completion, getting notified about their completion, and/or canceling them.
- 工作项允许您直接配置各个工作单元的属性。 它们还允许您处理单个工作单元,以便等待完成,获得完成通知和/或取消它们。
DispatchWorkItem
encapsulates work that can be performed. A work item can be dispatched onto a DispatchQueue
and within a DispatchGroup
. A DispatchWorkItem
can also be set as a DispatchSource
event, registration, or cancel handler.
- DispatchWorkItem封装了可以执行的工作。 可以将工作项分派到DispatchQueue和DispatchGroup中。 DispatchWorkItem也可以设置为DispatchSource事件,注册或取消处理程序。
DispatchWorkItemFlags
are an option set that configure the behavior of a DispatchWorkItem value, including its quality of service class and whether to create a barrier or spawn a new detached thread.
- DispatchWorkItemFlags是一个选项集,用于配置DispatchWorkItem值的行为,包括其服务质量类以及是创建障碍还是生成新的分离线程。
Prioritizing Work and Specifying Quality of Service
- 优先工作和指定服务质量
DispatchQoS
encapsulates quality of service classes.
- DispatchQoS封装了服务质量类。
DispatchQoS.QoSClass encapsulates quality of service classes.
- DispatchQoS.QoSClass封装了服务质量类。
Used to select the appropriate global concurrent queue.
- 用于选择适当的全局并发队列。
Using Dispatch Groups
Grouping blocks allows for aggregate synchronization. Your application can submit multiple blocks and track when they all complete, even though they might run on different queues. This behavior can be helpful when progress can’t be made until all of the specified tasks are complete.
- 分组块允许聚合同步。 您的应用程序可以提交多个块并跟踪它们是否完成,即使它们可能在不同的队列上运行。 在完成所有指定任务之前无法进行此操作时,此行为很有用。
DispatchGroup
allows for aggregate synchronization of work. You can use them to submit multiple different work items and track when they all complete, even though they might run on different queues. This behavior can be helpful when progress can’t be made until all of the specified tasks are complete.
- DispatchGroup允许工作的聚合同步。 您可以使用它们提交多个不同的工作项并跟踪它们何时完成,即使它们可能在不同的队列上运行。 在完成所有指定任务之前无法进行此操作时,此行为很有用。
Using Dispatch Semaphores
A dispatch semaphore is an efficient implementation of a traditional counting semaphore. Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked. If the calling semaphore does not need to block, no kernel call is made.
- 调度信号量是传统计数信号量的有效实现。 仅当需要阻止调用线程时,Dispatch信号量才会调用内核。 如果调用信号量不需要阻塞,则不进行内核调用。
DispatchSemaphore
provides an efficient implementation of a traditional counting semaphore, which can be used to control access to a resource across multiple execution contexts.
- DispatchSemaphore提供传统计数信号量的有效实现,可用于控制跨多个执行上下文的资源访问。
Using Dispatch Data
DispatchData
objects manage a memory-based data buffer. The data buffer is exposed as a contiguous block of memory, but internally, it may be comprised of multiple, discontiguous blocks of memory.
- DispatchData对象管理基于内存的数据缓冲区。 数据缓冲区作为连续的内存块公开,但在内部,它可能由多个不连续的内存块组成。
Using Dispatch Time
DispatchTime represents a point in time relative to the default clock with nanosecond precision. On Apple platforms, the default clock is based on the Mach absolute time unit.
- DispatchTime表示相对于具有纳秒精度的默认时钟的时间点。 在Apple平台上,默认时钟基于Mach绝对时间单位。
Base time constants. 基准时间常数。
DispatchTime
represents an absolute point in time according to the wall clock with microsecond precision. On Apple platforms, the default clock is based on the result of gettimeofday(2)
.
- DispatchTime表示根据具有微秒精度的挂钟的绝对时间点。 在Apple平台上,默认时钟基于gettimeofday(2)的结果。
DispatchTimeInterval
represents a number of seconds, millisconds, microseconds, or nanoseconds. You use DispatchTimeInterval
values to specify the interval at which a DispatchSourceTimer
fires or I/O handlers are invoked for a DispatchIO
channel, as well as to increment and decrement DispatchTime
values.
- DispatchTimeInterval表示秒数,毫秒,微秒或纳秒。 您可以使用DispatchTimeInterval值指定为DispatchIO通道调用DispatchSourceTimer触发或I / O处理程序的时间间隔,以及递增和递减DispatchTime值。
DispatchTimeoutResult
indicates whether a dispatch operation finised before a specified time.
- DispatchTimeoutResult指示在指定时间之前是否已完成调度操作。
A somewhat abstract representation of time.
-
有点抽象的时间表示。
-
Managing Dispatch Sources
DispatchSource
provides an interface for monitoring low-level system objects such as Mach ports, Unix descriptors, Unix signals, and VFS nodes for activity and submitting event handlers to dispatch queues for asynchronous processing when such activity occurs.
- DispatchSource提供了一个接口,用于监视低级系统对象,如Mach端口,Unix描述符,Unix信号和VFS节点,用于活动和提交事件处理程序,以便在发生此类活动时调度队列以进行异步处理。
protocol DispatchSourceProtocol
Defines a common set of properties and methods that are shared with all dispatch source types.
- 定义与所有调度源类型共享的一组公共属性和方法。
protocol DispatchSourceFileSystemObject
A dispatch source that monitors a file descriptor for events defined by DispatchSource.FileSystemEvent. The handle is a file descriptor (Int32
).
- 一个调度源,用于监视DispatchSource.FileSystemEvent定义的事件的文件描述符。 句柄是文件描述符(Int32)。
struct DispatchSource.FileSystemEvent
A file system event.
- 文件系统事件。
Managing Dispatch I/O
The dispatch I/O channel API lets you manage file descriptor–based operations. This API supports both stream-based and random-access semantics for accessing the contents of the file descriptor.
- 调度I / O通道API允许您管理基于文件描述符的操作。 此API支持基于流和随机访问语义,以访问文件描述符的内容。
DispatchO
provides a channel to perform operations on file descriptor using either stream-based and random-access semantics for accessing the contents of a file descriptor.
- DispatchO提供了一个通道,使用基于流的和随机访问语义对文件描述符执行操作,以访问文件描述符的内容。
1. dispatch_barrier_async
Submits a barrier block for asynchronous execution and returns immediately.
- 提交用于异步执行的屏障块并立即返回。
Parameters
queue
The dispatch queue on which to execute the barrier block. The queue is retained by the system until the block has run to completion. This parameter cannot be NULL.
- 要在其上执行屏障块的调度队列。 系统保留队列,直到块运行完成。 此参数不能为NULL。
block
The barrier block to submit to the target dispatch queue. This block is copied and retained until it finishes executing, at which point it is released. This parameter cannot be NULL.
- 阻止块提交到目标调度队列。 复制并保留此块,直到它完成执行,此时它将被释放。 此参数不能为NULL。
Discussion
Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked. When the barrier block reaches the front of a private concurrent queue, it is not executed immediately. Instead, the queue waits until its currently executing blocks finish executing. At that point, the barrier block executes by itself. Any blocks submitted after the barrier block are not executed until the barrier block completes.
- 调用此函数后,始终在提交块后立即返回,并且永远不会等待调用该块。 当障碍块到达专用并发队列的前面时,它不会立即执行。 相反,队列等待,直到其当前正在执行的块完成执行。 此时,屏障块自行执行。 在屏障块完成之后,在屏障块之后提交的任何块都不会执行。
The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create
function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_async
function.
- 您指定的队列应该是您使用dispatch_queue_create函数自己创建的并发队列。 如果传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为类似于dispatch_async函数。
2. dispatch_barrier_sync
Submits a barrier block object for execution and waits until that block completes.
- 提交屏障块对象以供执行,并等待该块完成。
Parameters
queue
The dispatch queue on which to execute the barrier block. This parameter cannot be NULL.
- 要在其上执行屏障块的调度队列。 此参数不能为NULL。
block
The barrier block to be executed. This parameter cannot be NULL.
- 要执行的障碍块。 此参数不能为NULL。
Discussion
Submits a barrier block to a dispatch queue for synchronous execution. Unlike dispatch_barrier_async
, this function does not return until the barrier block has finished. Calling this function and targeting the current queue results in deadlock.
- 将屏障块提交到调度队列以进行同步执行。 与dispatch_barrier_async不同,此功能在屏障块完成之前不会返回。 调用此函数并以当前队列为目标会导致死锁。
When the barrier block reaches the front of a private concurrent queue, it is not executed immediately. Instead, the queue waits until its currently executing blocks finish executing. At that point, the queue executes the barrier block by itself. Any blocks submitted after the barrier block are not executed until the barrier block completes.
- 当障碍块到达专用并发队列的前面时,它不会立即执行。 相反,队列等待,直到其当前正在执行的块完成执行。 此时,队列自己执行屏障块。 在屏障块完成之后,在屏障块之后提交的任何块都不会执行。
The queue you specify should be a concurrent queue that you create yourself using the dispatch_queue_create
function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like the dispatch_sync
function.
- 您指定的队列应该是您使用dispatch_queue_create函数自己创建的并发队列。 如果传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为类似于dispatch_sync函数。
Unlike with dispatch_barrier_async
, no retain is performed on the target queue. Because calls to this function are synchronous, it "borrows" the reference of the caller. Moreover, no Block_copy
is performed on the block.
- 与dispatch_barrier_async不同,不对目标队列执行保留。 因为对此函数的调用是同步的,所以它“借用”调用者的引用。 此外,不对块执行Block_copy。
As an optimization, this function invokes the barrier block on the current thread when possible.
- 作为优化,此函数在可能的情况下调用当前线程上的屏障块。
dispatch_semaphore_wait
Waits for (decrements) a semaphore.
Parameters
dsema
The semaphore. This parameter cannot be NULL
.
- 信号量。 此参数不能为NULL。
timeout
When to timeout (see dispatch_time
). The constants DISPATCH_TIME_NOW
and DISPATCH_TIME_FOREVER
are available as a convenience.
- 何时超时(请参阅dispatch_time)。 为方便起见,可以使用常量DISPATCH_TIME_NOW和DISPATCH_TIME_FOREVER。
Return Value
Returns zero on success, or non-zero if the timeout occurred.
- 成功时返回零,如果超时,则返回非零。
Discussion
Decrement the counting semaphore. If the resulting value is less than zero, this function waits for a signal to occur before returning.
- 减少计数信号量。 如果结果值小于零,则此函数在返回之前等待信号发生。
dispatch_semaphore_signal
Signals, or increments, a semaphore.
Return Value
If the previous value was less than zero, this function wakes a process currently waiting.
- 如果前一个值小于零,则此函数唤醒当前正在等待的进程。
Discussion
Increment the counting semaphore. If the previous value was less than zero, this function wakes a thread currently waiting in dispatch_semaphore_wait
.
- 增加计数信号量。 如果前一个值小于零,则此函数唤醒当前在dispatch_semaphore_wait中等待的线程。
dispatch_semaphore_create
Creates new counting semaphore with an initial value.
- 创建具有初始值的新计数信号量。
Parameters
value
The starting value for the semaphore. Do not pass a value less than zero.
- 信号量的起始值。 不要传递小于零的值。
Return Value
The newly created semaphore.
Discussion
Passing zero for the value is useful for when two threads need to reconcile the completion of a particular event. Passing a value greater than zero is useful for managing a finite pool of resources, where the pool size is equal to the value.
- 当两个线程需要协调特定事件的完成时,为值传递零是有用的。 传递大于零的值对于管理有限的资源池非常有用,其中池大小等于该值。
When your application no longer needs the semaphore, it should call dispatch_release
to release its reference to the semaphore object and ultimately free its memory.
- 当您的应用程序不再需要信号量时,它应调用dispatch_release以释放其对信号量对象的引用并最终释放其内存。
Important
Calls to dispatch_semaphore_signal
must be balanced with calls to wait()
. Attempting to dispose of a semaphore with a count lower than value
causes an EXC_BAD_INSTRUCTION
exception.
- 必须与对wait()的调用平衡对dispatch_semaphore_signal的调用。 尝试处理计数低于值的信号量会导致EXC_BAD_INSTRUCTION异常。
dispatch_sync
Submits a block object for execution on a dispatch queue and waits until that block completes.
- 提交块对象以在调度队列上执行,并等待该块完成。
Parameters
queue
The queue on which to submit the block. This parameter cannot be NULL.
- 提交块的队列。 此参数不能为NULL。
block
The block to be invoked on the target dispatch queue. This parameter cannot be NULL.
- 要在目标调度队列上调用的块。 此参数不能为NULL。
Discussion
Submits a block to a dispatch queue for synchronous execution. Unlike dispatch_async
, this function does not return until the block has finished. Calling this function and targeting the current queue results in deadlock.
- 将块提交到调度队列以进行同步执行。 与dispatch_async不同,此功能在块完成之前不会返回。 调用此函数并以当前队列为目标会导致死锁。
Unlike with dispatch_async
, no retain is performed on the target queue. Because calls to this function are synchronous, it "borrows" the reference of the caller. Moreover, no Block_copy
is performed on the block.
- 与dispatch_async不同,不对目标队列执行保留。 因为对此函数的调用是同步的,所以它“借用”调用者的引用。 此外,不对块执行Block_copy。
As an optimization, this function invokes the block on the current thread when possible.
- 作为优化,此函数在可能的情况下调用当前线程上的块。
dispatch_async
Submits a block for asynchronous execution on a dispatch queue and returns immediately.
- 在调度队列上提交异步执行块并立即返回。
Parameters
queue
The queue on which to submit the block. The queue is retained by the system until the block has run to completion. This parameter cannot be NULL.
- 提交块的队列。 系统保留队列,直到块运行完成。 此参数不能为NULL。
block
The block to submit to the target dispatch queue. This function performs Block_copy and Block_release on behalf of callers. This parameter cannot be NULL.
- 要提交到目标调度队列的块。 此函数代表调用者执行Block_copy和Block_release。 此参数不能为NULL。
Discussion
This function is the fundamental mechanism for submitting blocks to a dispatch queue. Calls to this function always return immediately after the block has been submitted and never wait for the block to be invoked. The target queue determines whether the block is invoked serially or concurrently with respect to other blocks submitted to that same queue. Independent serial queues are processed concurrently with respect to each other.
- 此函数是将块提交到调度队列的基本机制。 调用此函数后,始终在提交块后立即返回,并且永远不会等待调用该块。 目标队列确定是否相对于提交到同一队列的其他块串行或同时调用该块。 独立的串行队列相互同时处理。