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