标签:设置 如何 精简 分配 应用 文件读写 理由 uid 创建线程
关系:
①:先搞清两者的关系,NSOpertaionQueue用GCD构建封装的,是GCD的高级抽象!
②:GCD仅仅支持FIFO队列,而NSOperationQueue中的队列可以被重新设置优先级,从而实现不同操作的执行顺序调整。GCD不支持异步操作之间的依赖关系设置。如果某个操作的依赖另一个操作的数据(生产者-消费者模型是其中之一),使用NSOperationQueue能够按照正确的顺序执行操作。GCD则没有内建的依赖关系支持。
③:NSOperationQueue支持KVO,意味着我们可以观察任务的执行状态。
了解以上不同,我们可以从以下角度来回答
性能:①:GCD更接近底层,而NSOperationQueue则更高级抽象,所以GCD在追求性能的底层操作来说,是速度最快的。这取决于使用Instruments进行代码性能分析,如有必要的话
②:从异步操作之间的事务性,顺序行,依赖关系。GCD需要自己写更多的代码来实现,而NSOperationQueue已经内建了这些支持
③:如果异步操作的过程需要更多的被交互和UI呈现出来,NSOperationQueue会是一个更好的选择。底层代码中,任务之间不太互相依赖,而需要更高的并发能力,GCD则更有优势
最后的一句话:别忘了高德纳的教诲:“在大概97%的时间里,我们应该忘记微小的性能提升。过早优化是万恶之源。”只有Instruments显示有真正的性能提升时才有必要用低级的GCD。
进程的同步机制原子操作 信号量机制 自旋锁 管程,会合,分布式系统
进程之间通信的途径:共享存储系统消息传递系统管道:以文件系统为基础
进程死锁的原因:资源竞争及进程推进顺序非法
死锁的4个必要条件:互斥、请求保持、不可剥夺、环路
死锁的处理:鸵鸟策略、预防策略、避免策略、检测与解除死锁
线程是进程的基本单位。
进程和线程都是由操作系统所产生的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。
进程有独立的地址空间,一个进程崩溃后,在保护模式下 不会对其它进程产生影响。
线程只是一个进程中的不同执行路径。
线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。
但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
不是的。
atomic原子操作,系统会为setter方法加锁。 具体使用 @synchronized(self){//code }
nonatomic不会为setter方法加锁。
atomic:线程安全,需要消耗大量系统资源来为属性加锁
nonatomic:非线程安全,适合内存较小的移动设备
使用atomic并不能保证绝对的线程安全,对于要绝对保证线程安全的操作,还需要使用更高级的方式来处理,比如NSSpinLock、@syncronized等
推出的时间 iOS4 目的是用来取代NSThread(ios2.0推出)的,是 C语言框架,它能够自动利用更多CPU的核数,并且会自动管理线程的生命周期。
队列又分为四种种:1 串行队列 2 并发队列 3 主队列 4 全局队列
执行任务的两个函数
"同步"和"异步"的区别:
各个队列的执行效果:
线程间通讯:经典案例:子线程进行耗时操作(例如下载更新等)主线程进行UI刷新。
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
延迟操作
调用 NSObject 方法:[self performSelector:@selector(run) withObject:nil afterDelay:2.0];
// 2秒后再调用self的run方法
GCD函数实现延时执行:dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 2秒后执行这里的代码... 在哪个线程执行,跟队列类型有关
队列组的使用:
项目需求:首先:分别异步执行两个耗时操作;其次:等两次耗时操作都执行完毕后,再回到主线程执行操作.使用队列组(dispatch_group_t)快速,高效的实现上述需求.
dispatch_group_t group = dispatch_group_create(); // 队列组
dispatch_queue_t queue = dispatch_get_global_queue(0, 0); // 全局并发队列
dispatch_group_async(group, queue, ^{// 异步执行操作1
// longTime1
});
dispatch_group_async(group, queue, ^{ // 异步执行操作2
// longTime2
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 在主线程刷新数据
// reload Data
});
? 对于queue中所执行的代码不一定在main thread中。如果queue是在主线程中创建的,那么所执行的代码就是在主线程中执行。如果是在子线程中创建的,那么就不会在main thread中执行。
? 对于main queue就是在主线程中的,因此一定会在主线程中执行。获取main queue就可以了,不需要我们创建,获取方式通过调用方法dispatchgetmain_queue来获取。
使用Dispatch Group追加block到Global Group Queue,这些block如果全部执行完毕,就会执行Main Dispatch Queue中的结束处理的block。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
dispatch_group_async(group, queue, ^{ /*加载图片3 */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
});
1. 对于这四个异步请求,要判断都执行完成最简单的方式就是通过GCD的group来实现:
2. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
3. dispatch_group_t group = dispatch_group_create();
4. dispatch_group_async(group, queue, ^{ /*任务a */ });
5. dispatch_group_async(group, queue, ^{ /*任务b */ });
6. dispatch_group_async(group, queue, ^{ /*任务c */ });
7. dispatch_group_async(group, queue, ^{ /*任务d */ });
8.
9. dispatch_group_notify(group, dispatch_get_main_queue(), ^{
10. // 在a、b、c、d异步执行完成后,会回调这里
11. });
当然,我们还可以使用非常老套的方法来处理,通过四个变量来标识a、b、c、d四个任务是否完成,然后在runloop中让其等待,当完成时才退出run loop。但是这样做会让后面的代码得不到执行,直到Run loop执行完毕。
要求顺序执行,那么可以将任务放到串行队列中,自然就是按顺序来异步执行了
从题目分析可知,10个请求要全部完成后,才执行某一功能。比如,下载10图片后合成一张大图,就需要异步全部下载完成后,才能合并成大图。
做法:通过dispatch_group_t来实现,将每个请求放入到Group中,将合并成大图的操作放在dispatch_group_notify中实现。
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{ /*加载图片1 */ });
dispatch_group_async(group, queue, ^{ /*加载图片2 */ });
dispatch_group_async(group, queue, ^{ /*加载图片3 */ });
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 合并图片
});
http://www.dreamingwish.com/article/gcd-guide-dispatch-once-2.html(超级详细解析)
个人觉得说出实现的思路即可,无锁的线程同步编程,每一处的线程竞争都考虑到并妥善处理
线程A执行Block时,任何其它线程都需要等待。
GCD
NSOperation
线程创建有三种方法:使用NSThread创建、使用GCD的dispatch、使用子类化的NSOperation,然后将其加入NSOperationQueue;
NSThread创建线程的三种方法:
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"nil"];
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"我是分离出来的子线程"];
[self performSelectorInBackground:@selector(run:) withObject:@"我是后台线程"];
在主线程执行代码,就调用performSelectorOnMainThread方法。
如果想延时执行代码可以调用performSelector:onThread:withObject:waitUntilDone:方法;
GCD:
利用异步函数dispatch_async()创建子线程。
在主线程执行代码,dispatch_async(dispatch_get_main_queue(), ^{});
延迟执行代码(延迟·可以控制代码在哪个线程执行):
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{});
NSOperationQueue:
使用NSOperation的子类封装操作,再将操作添加到NSOperationQueue创建的队列中,实现多线程。
在主线程执行代码,只要将封装代码的NSOperation对象添加到主队列就可以了。
A. GCD所用的开销要比NSThread大
B. 可以在子线程中修改UI元素
C. NSOperationQueue是比NSthread更高层的封装
D. GCD可以根据不同优先级分配线程
标签:设置 如何 精简 分配 应用 文件读写 理由 uid 创建线程
原文地址:http://www.cnblogs.com/weiming4219/p/7649661.html