线程和进程
一般而言进程包含如下3个特征:
- 独立性:进程是系统中独立存在的实体,拥有自己独立的资源,拥有自己私有的地址空间。在没有进过进程本身允许的情况下,一个用户进程不可以直接访问其他进程的地址空间。
- 动态性:程序只是一个静态的指令集合,而进程是一个正在系统中活动的指令集合。
- 并发性:多个进程可以在单个处理器上并发执行,多个进程间不会互相影响。
并发性和并行性是两个概念,并行指在同一时刻有多条指令在多个处理器上同时执行;
并发指在同一时刻只能有一条指令执行,但多个进程指令被快速轮换执行,使得在
宏观上具有多个进程同时执行的效果。
线程
- 多线程扩展了多进程的概念,使得一个进程可以同时并发处理多个任务。线程也被称为轻量级进程,线程是进程的执行单元。当进程被初始化后,主线程就被创建了。
- 线程可以拥有自己的堆栈、自己的程序计数器和自己的局部变量,但不再拥有系统资源,它与父进程的其他线程共享改进程所拥有的全部资源。一个线程可以撤销和创建另一个线程,同一个进程中的线程之间可以并发执行。
多线程的优点
- 进程间不能共享内存,但线程之间共享内存非常容易。
- 系统创建进程需要为该进程重新分配系统资源,但创建线程代价小的多,因此使用多线程来实现多任务并发比多进程的效率高。
创建线程
- 使用实例方法,返回一个NSThread对象,必须调用start方法启动线程:
NSThread *thread = [[NSThread alloc]initWithTarget:self
selector:@selector(run)
object:nil];
[thread start];
[NSThread detachNewThreadSelector:@selector(run)
toTarget:self withObject:nil];
程序可以通过setName:方法为线程设置名字
线程状态
- 当程序创建线程后,该线程处于新建状态,仅仅由系统为其分配了内存,并初始化其成员变量的值;当线程对象调用了start方法后,该线程处于就绪状态,系统会为其创建方法调用栈和程序计数器,处于这种状态中的线程并没有开始运行,它只是表示该线程可以运行了,至于何时运行取决于系统的调度。
- 如果希望调用子线程的start方法后子线程立即开始执行,程序可以使用[NSThread sleepForTimeInterval:0.001];让当前运行的线程(主线程)睡眠1毫秒。
终止线程
线程会以一下3中方式之一结束:
- 线程执行体方法执行完成,线程正常结束
- 线程执行过程中出现了错误
- 直接调用NSThread类的exit方法来终止当前正在执行的线程
当主线程结束时,其他线程不受任何影响,并不会随之结束。一旦子线程启动起来后,它就
拥有和主线程相同的地位。为了测试某个线程是否正在运行,可以调用线程对象的
isExecuting、isFinished方法;如果希望在UI中终止子线程,NSThread并没有提供
方法来终止某个线程,可以通过先执行[thread cancel]改变线程状态,然后在此线程
执行体方法中使用[NSThread currentThread].isCancelled判断thread对象的状态,
如果isCancelled为YES,就使用[NSThread exit]终止当前子线程。
线程睡眠
如果需要将当前正在执行的线程暂停一段时间,并进入阻塞状态,可以通过以下方法实现:
[NSThread sleepForTimeInterval:t];
[NSThread sleepUntilDate:aDate];
回调主线程刷新UI一般使用以下方法:
[self performSelectorOnMainThread:@selector(updateUI:)
withObject:image waitUntilDone:YES];
或者
dispatch_async(dispatch_get_main_queue(), ^{...});
改变线程的优先级
每个线程执行时都具有一定的优先级,优先级高的线程获得较多的执行机会。NSThread提供如下方法设置获取线程的优先级:
[NSThread threadPriority];
[thread threadPriority];
[NSThread setThreadPriority:priority];
[thread setThreadPriority:priority];