IOS多线程(一)
一。绪论
1.进程:平时看到的一个应用程序,即可算作一个线程。
每个进程都有一个PID作为进程ID,有一个Process Name作为进程名字等。
2.线程:一个进程可以有多个线程,而每个线程只可属于一个进程。
开发者可以创建其他线程来配合主线程的工作,但是子线程一般只用做逻辑处理的执行流程。
无论是MacOSX还是IOS,界面的处理都必须放在主线程中进行。
ios SDK支持多线程,并且提供了NSOperation和NSOperationQueue类来方便多线程编写。
*******************************
二。NSThread
1.在单个程序中同时运行多个线程完成不同的工作,称为多线程。
2.在ios SDK上,NSThread类实现多线程。
3.如果有太多的线程在执行的话,系统可能就会瘫痪。一个解救方法:创建少一点的线程。
i。NSOperationQueue类实现。
ii。sleep:可以让一个线程sleep一段时间或者是让它在某一个时间点被唤醒。在sleep的这段时间内,该线程就把系统的时间片交给了其他的线程。
如果你想让线程休眠特定的时间,调用NSThread的类方法:sleepForTimeInterval:
[NSThread sleepForTimeInterval:2.5];
如果你想让线程在某个特定的时刻被唤醒就用方法:sleepUntilDate:
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.5]];
4.NSThread类库也支持开发者的一些配置,如果需要配置新线程属性的话,就不用使用类方法这种以默认方式快速创建对象的方法了,代之直接使用NSThread的start方法即可。
例子:
NSThread *newThread = [[NSThread alloc] initWithTarget:self
selector:@selector(newThread:)
object:@"hello"];
[newThread setName:@"HelloThread"];
[newThread setStackSize:4*1024]; //4KB的整数倍
[newThread setThreadPriority:1.0f];
[newThread start];
5.NSThread提供了大部分平时在控制线程时的方法,并且NSThread最清楚当前线程的状况。
判断当前线程是否为主线程:[NSThread isMainThread];
判断当前是否是多线程状态:[NSThread isMultiThreaded];
当前线程的信息:[[NSThread currentThread] threadDictionary];
需要提前结束线程:[NSThread exit];
*******************************
三。pthread(了解即可)
POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32。
*******************************
四。NSOperation(操作)和NSOperationQueue(操作队列)
1.operation就是一些指令的集合,然后由operation queue来管理。
2.这里每一个operation基本上都是NSOperation子类的实例。ios提供了NSOperation的一个子类叫做NSInvocationOperation(调用队列),在这个类中可以指定一个对象和一个selector。
3.operation的依赖性:
任何一个operation都能选择性地和另一个或几个operation存在一定的依赖性。
例如:一个operation要在另一个operation之前完成,因此operation queue就会知道线完成哪一个operation。
添加依赖关系:
返回一个operation所有的依赖关系:
移除一个operation的某一个依赖关系:
4.operation的优先级:
优先级状态(5种):
设置每个operation的优先级:setQueuePriority方法。
5.operation的状态:
operation的一些成员变量能够放映其状态。
像:isCancelled:反映一个operation是否被取消。
6.取消一个operation:
用cancel方法来取消一个operation。
例如:[firstOperation cancel];
以上都是operation,下面是operarion queue。
7.operation queue:
创建一个operation queue和创建其他的对象一样:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
向新创建的operation queue添加operation:
[queue addOperation:newOperation];
*******************************
五。GCD
1.从MacOSX10.6和IOS4.0开始,苹果提供给开发者一个多线程并发的类库供开发者使用。这个类库名为“Grand Central Dispatch”,平时大家都简称为GCD。
2.GCD提供了一套C语言的方法列表,利用这些方法开发者不仅能够做到和之前NSThread同样多的事情,并且更重要的一点是,此类库可以让开发者跳过负载平衡的课题,直接让应用程序在多核的设备或者电脑上本质上加强性能和工作效率。
3.GCD提供了一种很简单的操作方式来实现并行处理,可以把要并发执行的代码放在一个block上,然后把这个block加入到一个queue当中。
4.GCD的使用方法大致浏览下来,大多需要和block语法配合起来展现威力。
5.在GCD中为我们需要执行的block提供了3种队列:
Main:
Concurrent:
Serial:
6.对于系统提供的3个默认队列来说,当需要获得他们的时候,只需要通过下列方法即可。
dispatch queue t dispatch get global queue(long priority, unsigned long flags);
7.获得一个concurrent队列,使用:dispatch_global_queue()方法。
8.获得一个main队列,使用:dispatch_get_main_queue()方法。
9.创建一个队列,使用:dispatch_queue_create()方法。
10.如果想在后台完成一些任务,就把指令包裹在一个block上,然后把这个block加入到指定的队列中。
如:dispatch_async(我们请求加入的队列,我们要加入的block)。
11.同步:dispatch_async
异步:dispatch_sync
需要多次执行一段同步任务:dispatch_apply
*******************************
六。线程安全
为了解决多线程之间使用所产生冲突的问题,苹果味开发者提供了多种解决方案。
1.NSLock的使用(需要熟悉“信号量”和“互斥机制”)
i。申请到信号量:lock方法。
tryLock:在申请不到信号量时不会让当前线程等待在那里,而是马上返回NO后继续执行下面代码。
lockBeforeDate:让当前线程等待到指定日期后才放弃等待。
ii。NSLock并非没有缺点,它有3个固有问题需要重视。
2.synchronized的使用
a。苹果常被认为是一家相当会提供补丁方案的公司,当苹果发现开发者对于NSLock使用烦琐而频繁抱怨后,立即意识到需要为开发者再多做一些事情搞定容易出问题的NSLock。这个新的解决方案就是@synchronized关键字。
b。@synchronized关键字能够对任何一个对象进行加锁,一旦加锁后,对这个对象发送的消息将会被阻塞,直到@synchronized所管理的那段关键代码执行完毕后自动将此对象解锁为止。
c。在使用@synchronized时苹果也为它提供了自动的异常处理机制,一旦出现问题会抛出异常给系统,系统会将此异常返回个应用程序,所以如果我们在应用程序中没有一套有效的处理异常的框架,就最好不要用@synchronized,以避免异常没有接受者。
3.condition的使用
在线程安全中,处理多个线程抢资源这种互斥形式外,还有一种互相依赖的形式。
例如:将A理解为信号量的产生者,将B理解为信号量的消费者。最理想的情况下,B等待在那里直到A完成任务将B唤醒后,B继续执行自己的任务。
互相依赖锁的实现可以使用NSConditionLock类库或者NSCondition来撰写。