iOS中的 mutex 对应的是 NSLock,它遵循 NSLooking协议,我们可以使用 lock, tryLock, lockBeforeData:来加锁,用 unLock来解锁。使用示例: BOOL moreToDo = YES; NSLock *theLock = [[NSLock alloc] init]; ... while (moreToDo) { /* Do another increment of calculation */ /* until there’s no more to do. */ if ([theLock tryLock]) { /* Update display used by all threads. */ [theLock unlock]; } }
我们可以使用指令 @synchronized 来简化 NSLock的使用,这样我们就不必显示编写创建NSLock,加锁并解锁相关代码。 - (void)myMethod:(id)anObj { @synchronized(anObj) { // Everything between the braces is protected by the @synchronized directive. } }
Runloop顾名思义就是一个不停的循环,不断的去check输入,如下图。 我们需要了解runloop modes这对判断事件来源以及添加到runloop时很有必要。 正如之前我们所说,只有创建了次线程才需要我们管理runloop,但是也并不是创建了次线程就一定需要管理runloop,仅当: o Use ports or custom input sources to communicate with other threads. o Use timers on the thread. o Use any of the performSelector... methods in a Cocoa application. o Keep the thread around to perform periodic tasks. 你还可以注册runloop,这样可以使用kvo。 · NSTask: 使用task你可以运行其它程序作为当前程序的子进程,并监控它的运行。它和线程的不同之处在于它并不何创建它的进程(父进程)共享内存。可以说是“完全”独立的一个东西。
1. 关于多线程编程 多年以来,计算机的性能在很大程度上被单核处理器的速度所限制。在当前技术下,单核处理器的速度已经到达某种极限,因此,芯片制造商们转而专注于多核设计,以使计算机可以同时执行多个任务。Mac OS X 可以利用多核计算,更好的执行系统相关的任务。而开发人员也可以通过线程提高自己程序的性能。 1) 什么是线程?
Table 1-1 列出了可供选择的线程实现方式。表中包含了线程的替代技术(操作对象-- operation object 和Grand central Dispatch),还包含了旨在提高效率的单线程技术。
Table 1-1 Alternative technologies to threads Technology Description Operation objects| Mac OS X v10.5后被引入,一个操作对象是一项任务的封装,可以被子线程们来执行。使用这样的封装技术,可以忽略线程管理方面的麻烦,使程序员专注于任务本身。通常情况下,我们搭配使用操作队列对象(operation queue object)来使用操作对象。操作队列对象会管理操作对象在多线程中的执行。具体内容参考Concurrency Programming Guide.
Grand Central Dispatch |Mac OS X v10.6后被引入,Grand Central Dispatch是让我们专注于任务本身而非线程管理的另外的选择。使用Grand Central Dispatch,我们定义一项任务,并将其加入到一个工作队列中,队列会负责在合适的线程中执行任务。队列还会查看可用内核的数量和当前任务负载,从而比自己使用线程更高效的执行任务。
线程间通信有很多方式,各有优劣,“Configuring Thread-Local Storage” 表中罗列了在Mac OS X上常用到的通信机制(除了消息队列(message queue)和Cocoa分布式对象(Cocoa distributed object)外,其他也可以在iOS上通用)。详细列表如下:
Table 1-3 Communication mechanisms Direct messaging|Cocoa程序支持直接在其他线程中执行方法(perform selector)。这个功能意味着一个线程可以直接在另外一个线程中执行方法。因为要在目标线程中执行,通过这种方法发送的消息会在线程中被自动序列化。关于input sources的详细信息,请查看“Cocoa Perform Selector Sources.”(后章会有详细说明)。
Global variables, shared memory, and objects |另外一种通信的方式就是使用全局变量、共享对象,或是共享内存块。虽然共享变量既快又简单,这种方式相比较直接消息方式更加脆弱。必须使用锁或者其他同步机制来“保护”共享变量。否则,可能导致线程间的竞争状态、数据被损坏,或程序崩溃。