并行编程旨在解决如何更高效的使用多核处理器来处理一个程序内的多个并发任务问题。(用户界面,后台任务)现代的并行编程技术,在OSX和iOS平台上主要使用的是GCD(大型中央调度),这个技术比传统的thread管理好的地方是,它是基于操作系统级别的,剥离了应用程序,节约了线程的调用堆栈。其次对于不同平台,GCD可以统一管理,类似某种线程池的技术,对于不同的系统,和系统的运行状态,自动处理thread的各种问题。Operation Objects是基于GCD封装的Objective-C对象。

并行程序设计

Dispatch Queues
dispatch queues 是 基于C的可以执行定制任务的机制。分为serial queue和concurrent queue,顾名思义,分别是连环任务队列和并行任务队列。serial queue一次只能执行一个任务,此任务完成后,下个任务出列执行。concurrent queue 同时执行所有任务,不用等待上个完成。
Dispatch Queue 还有以下特性:
• 他们提供了直接喝简单的编程接口
• 他们有自动和完整的线程池管理
• 他们提供了调整装配的速度
• 他们更节约内存
• 任务异步调度到一个dispatch queue不会死锁队列
• 在资源竞争中优雅的伸缩。
• 连环dispatch queue对其他线程同步方法来说有更好效果
提交到dispatch queue的任务必须包装在一个 block object内。block objects 是一个c语言特性,类似于函数指针,但是有更多特性。

Dispatch Sources
是一种基于C的机制,用于异步处理特定类型的系统事件,封装有关特定类型系统事件的信息,并在发生该事件时将特定块对象或函数提交给dispatch queue。可以使用dispatch source来监视以下类型的系统事件:

• Signal handlers
• Timers
• Descriptor-related events
• Process-related events
• Mach port events
• Custom events that you trigger

Operation Queues

是Cocoa实现的dispatch queue的等价物。即NSOperationQueue,先进先出的队列,支持dependency属性。

Dispatch Queues
有 dispatch_async 和dispatch_sync方法,其中 sync方法会阻塞当前线程,等待queue的block程序完成后,接触阻塞。所以,当sync的参数queue和当前线程所在的队列是同一个队列时,或造成死锁。

并发的循环,dispatch_apply, 此方法用于完成一个并发的循环,直接目的相当于在一个dispatch queue中,并发的执行某个block,效果等同于loop,但是需要注意的是,当dispatch_apply的参数queue和当前线程所在的dispatch queue是同一个时,也会造成死锁。原因和dispatch sync一样。

dispatch_suspend和dispatch_resume用于控制queue的阻塞和恢复
使用 dispatch semaphore 来限制使用有限的资源,有 dispatch semephore wait,sign等方法
使用 dispatch group wait 来等待一组异步队列的任务

Dispatch Sources
一般用户调度系统的各种事件給queue,使用event handler在queue里处理这些。无论何时你与底层系统进行交互,你都必须为该任务做好准备,以便花费很少的时间。调用内核或其他系统层涉及上下文的变化,与您自己的进程中发生的调用相比,这种变化相当昂贵。因此,许多系统库提供异步接口以允许您的代码向系统提交请求,并在处理该请求时继续执行其他工作。 GCD通过允许您提交请求并使用block和dispatch queue将结果报告回您的代码来构建此一般行为。目的在于接受系统事件处理。主要有以下几种形式:

• Timer dispatch sources 生成周期性的消息.
• Signal dispatch sources 当一个unix事件到来时提示
• Descriptor sources 文件和socket的操作到来时提醒,包括以下:
◦ When data is available for reading 当数据可读时
◦ When it is possible to write data 当可写数据时
◦ When files are deleted, moved, or renamed in the file system 当文件删除,移动重命名时
◦ When file meta information changes 当文件meta data修改时

• Process dispatch sources 提示进程相关事件,如:
◦ When a process exits 当一个进程存在
◦ When a process issues a fork or exec type of call 当一个进程在fork或exec时出现问题时
◦ When a signal is delivered to the process 当一个信号传递给进程时

• Mach port dispatch sources 通知mach port相关事件
• Custom dispatch sources 自定义dispatch source
Create dispatch source
创建dispatch source涉及创建event source和dispatch source本身两件事。event source是处理事件所需的本地数据结构。例如,对于基于descriptor-based的调度源,您需要打开descriptor;对于process-based的源,您需要获取目标程序的进程ID。当有event source时,你可以创建相应的dispatch source,如下所示:
1. 使用dispatch_source_create 创建source
2. 配置这个source,包括:
• 指定一个event handler給这个source
• 对于timer source,使用 dispatch_source_set_timer方法,创建timer
3. 指定一个cancel handler(可选)
4. Call dispatch_resume方法启动这个source
由于dispatch source在可以使用之前需要一些额外的配置,因此dispatch_source_create函数会将dispatch source返回到挂起状态。暂停时,dispatch source会收到事件但不处理它们。提供了安装事件处理程序的时间,并执行处理实际事件所需的任何其他配置。

使用dispatch_source_set_event_handler 或者 dispatch_source_set_event_handler_f 方法对到来的事件进行处理,enent handler的主体负责处理任何到达的事件。如果您的事件处理程序已经进入队列并开始等待处理一个事件了,此时有一个新事件来了,这时调度源会合并这两个事件。事件处理程序通常仅查看最近事件的信息,但根据dispatch source的类型,它也可以获取一些已发生合并的其他事件的信息。如果在事件处理程序开始执行之后有一个或多个新事件到达,则dispatch source会保留这些事件,直到当前事件处理程序执行完毕。此时,它会使用新事件再次将事件处理程序提交给队列。

创建 source timer ,和所有其他timer一样,有规律的在queue中执行event handler。

end