ios线程和GCD和队列同步异步的关系
1、什么是进程?
进程是指在系统中正在运行的一个应用程序。比如同时打开QQ、Xcode,系统就会分别启动2个进程。截图
2、什么是线程?
1)、一个进程要想执行任务,必须得有线程(每一个进程至少要有一条线程)
2)、线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行
3)、一个线程中任务的执行是串行的。即如果要在1个线程中执行多个任务,那么只能一个一个的按顺序执行这些任务
3、什么是多线程?
1)、一个线程中可以开启多条线程,每条线程可以并行执行不同的任务。比如同时开启三条线程分别下载3个文件
2)、同一时间,CPU只能处理一条线程,只有一条线程在工作(执行)
3)、多线程并发(同时)执行,其实是CPU快速的在多线程之间调度(切换)
4)、如果cpu调度线程的时间足够快,就造成了多线程并发执行的假象
5)、如果线程非常非常多,那么会发生什么情况呢?
可能导致cpu在N条线程之间调度,消耗大量的cpu资源,进而导致每条线程被调度执行的频次会降低(线程的执行效率降低)
6)、多线程的优点:能适当提高程序的执行效率;能适当提高资源利用率(cpu、内存利用率)
7)、多线程的缺点:
开启线程需要占用一定的内存空间(默认情况下,主线程占用1M,子线程占用512KB),如果开启大量的线程,会占用大量的内存空间,降低程序的性能;
线程越多,cpu在调度线程上的开销就越大;
程序设计更加复杂:比如线程之间的通信、多线程的数据共享
4、什么是主线程
1)、一个ios程序运行后,默认会开启一条线程,称为”主线程“或”UI线程“
2)、主线程的作用:
显示/刷新UI界面;
处理UI事件(比如点击事件、滚动事件、拖拽事件等)
3)、主线程的使用注意:
别将比较耗时的操作放到主线程中;耗时操作会卡住主线程,严重影响UI的流畅度,给用户一种”卡“的坏体验;
所以一般将耗时操作放在子线程(后台线程、非主线程)
5、ios中多线程的实现方案:
6、NSThread
1)一个NSThread对象就代表一条线程
2)创建、启动线程:
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(testThread) object:nil];
[thread start];
3)、主线程相关用法:
+ (NSThread *)mainThread; //获取主线程
- (BOOL)isMainThread; //是否为主线程
+ (BOOL)isMainThread; //是否为主线程
4)、获取当前线程: NSThread *current = [NSThread currentThread];
5)、线程的调度优先级
+ (double)threadPriority;
+ (BOOL)setThreadPriority:(double)p;
- (double)threadPriority;
- (BOOL)setThreadPriority:(double)p;
调度优先级的取值范围是0.0 ~ 1.0, 默认是0.5, 值越大,优先级越高
6)、线程的名字:- (void)setName: (NSString *)n; - (NSString *)name;
7)、另外一种创建线程方法:创建线程后启动线程:
[NSThread detachNewThreadSelector:@selector(testThread) toTarget:self withObject:nil];
8)、第三种创建线程方式:隐式创建并启动线程:
[self performSelectorInBackground:@selector(testThread) withObject:nil];
9) 、后面2中创建线程方式的优缺点:
优点:简单快捷
缺点:无法对线程进行更详细的设置
10)、阻塞(暂停)线程:
+ (void)sleepUnitilDate:(NSDate *)date; //睡眠到date这个时间上
+ (void)sleepForTimeInterval:(NSTimeInterval)seconds; //睡眠seconds秒
调用这两个方法中任一方法,当前线程会睡眠(暂停)所设置的时间后,才会执行后面的操作
11)、强制停止线程,让当前线程提前结束它的生命:+ (void)exit;
7、多线程安全问题 - 互斥锁
1)、互斥锁使用方式:@synchronized(所对象) { //需要锁定的代码 } ; // 线程同步:多条线程按顺序地执行任务
2)、互斥锁的优缺点:
优点:能有效防止因多线程抢夺同一资源造成的数据安全问题;
缺点:需要消耗大量的CPU资源
8、原子和非原子属性
OC在定义属性时有nonatomic和atomic两种选择
atomic : 院子属性,为setter方法加锁(默认就是atomic)
nonatomic:非原子属性,不会位setter方法加锁
---------------- nontomic 和 atomic对比 -------
atomic :线程安全,需要消耗大量的资源;
nonatomic : 非线程安全,适合内存晓得移动设备
------ 对于设置属性原子和非原子性的建议 ---
a、所有属性都声明位nontomic;
b、尽量避免多线程抢夺同一块资源;
c、尽量将加锁、资源抢夺的业务逻辑交给服务端处理,减小移动客户端的压力。
9、线程间通信
在1个线程中,线程往往不是孤立存在的,多个线程之间需要经常进行通信:比如说一个线程传递数据给另一个线程,又或者在一个线程中执行完成特定任务后,转到另一个线程继续执行任务。
线程间通信常用方法:
- (void)performSelectorOnMainThread:(SEL)aSelectorWithObject:(id)arg waitUntilDone:(BOOL)wait; //传递数据到主线程
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait; //传递数据到另一个线程
10、GCD
1)、GCD,全称是Grand Central Dispatch,伟大的中央调度器。纯C语言,提供了非常多强大的函数
2)、GCD的优势:
GCD是苹果公司位多核的并行运算提出的解决方案;会自动利用更多的CPU内核;
会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
3)、GCD中2个核心概念:任务和队列。任务指执行什么操作,队列是用来存放任务。
GCD的使用步骤:
a、定制任务。确定想做的事;
b、将任务添加到队列中。GCD会自动将队列中的任务取出,放到对应的线程中执行 ;任务的取出遵循队列的FIFO原则:先进先出。
GCD执行任务函数:
用同步的方式执行任务:dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); // queue指队列 ; block指任务
用异步的方式执行任务:dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
同步和异步的区别:同步只能在当前的线程中执行任务,不具备开启新线程的能力; 异步可以在新的线程中执行任务,具备开启新线程的能力;
4)、队列的类型:主要分为并发队列和串行队列
并发队列:Concurrent Dispatch Queue, 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务);
并发功能只有在异步(dispatch_async)函数下才有效
串行队列:Serial Dispatch Queue, 让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
并行队列:
GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建;
使用dispatch_get_global_queue函数获得全局的并发队列;
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags); //priority指队列的优先级, flags参数暂时无用,用0即可
示例:dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //获得全局并发队列
全局并发队列的优先级:
#define DISPATCH_QUEUE_PRIORITY_HIGH 2//高
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0//默认(中)
#define DISPATCH_QUEUE_PRIORITY_LOW (-2) //低
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN //后台
串行队列:
使用dispatch_queue_create函数创建一个串行队列
dispatch_queue_create(const char *lable, dispatch_queue_attr_t attr); //lable参数指队列名称;attr参数指队列属性,一般用NULL即可
另外可以使用主队列:dispatch_get_main_queue(),主队列是GCD自带的一种特殊的串行队列;放在主队列中的任务,都会放到主线程中执行
-----------------------------------------------------
线程和队列、异步同步函数的关系?
1、一个应用程序表示开启了一个进程
2、一个进程至少有一个线程,即至少有一个主线程,也可以开启多条线程
3、一个线程中可以有多个队列,每个队列中可以执行多个任务
4、在线程中执行任务的顺序可以是按顺序来执行,也可以用不按顺序来执行。即表现为串行和并行
5、那异步和同步函数的作用在哪里?
是否开启多条线程,然后执行的队列(任务)是否按顺序还是不按顺序执行,都需要异步和同步函数的配合才能实现!
并行和串行队列,与异步同步函数的排列组合有如下这些:
a、并行队列 + 异步函数 开启多条线程,不按顺序执行任务;
b、串行队列 + 异步函数 开启一条新线程,按顺序执行任务;
c、主队列 + 异步函数不开启新线程,按顺序执行任务
d、并行队列 + 同步函数不开启新线程,按顺序执行任务;
e、串行队列 + 同步函数不开启新线程,按顺序执行任务;
f、主队列 + 同步函数会出现卡死现象!原因:循环等待,主队列的东西要等主线程执行完,又不能开线程,
所以下面的任务要等上面的任务执行完,然后卡死
举例说明:
1、并行队列 + 异步函数:开启多条线程,不按顺序执行任务 (全局队列+异步函数效果一样)
dispatch_queue_t q1 = dispatch_queue_create("mulQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = ; i < ; i++){
dispatch_async(q1, ^{
NSLog(@"并行+异步,i=%d, currentThread: %@", i, [NSThread currentThread]);
});
}
NSLog(@"并行队列+异步函数测试执行 end....");
/*
并行队列+异步函数测试执行 end....
并行+异步,i=1, currentThread: <NSThread: 0x60000026ab80>{number = 5, name = (null)}
并行+异步,i=0, currentThread: <NSThread: 0x600000269b00>{number = 3, name = (null)}
并行+异步,i=4, currentThread: <NSThread: 0x60000026ea80>{number = 7, name = (null)}
并行+异步,i=3, currentThread: <NSThread: 0x600000269bc0>{number = 6, name = (null)}
并行+异步,i=5, currentThread: <NSThread: 0x60800026d8c0>{number = 8, name = (null)}
....
并行+异步,i=97, currentThread: <NSThread: 0x600000272f80>{number = 49, name = (null)}
并行+异步,i=99, currentThread: <NSThread: 0x600000273000>{number = 50, name = (null)}
并行+异步,i=98, currentThread: <NSThread: 0x60000026ad40>{number = 11, name = (null)}
*/
2、并行 + 同步:不开启线程,按顺序执行,在主线程执行
dispatch_queue_t q2 = dispatch_queue_create("mulQueue", DISPATCH_QUEUE_CONCURRENT);
for (int i = ; i < ; i++){
dispatch_sync(q2, ^{
NSLog(@"并行+同步,i=%d, currentThread: %@", i, [NSThread currentThread]);
});
}
NSLog(@"并行队列+同步函数测试执行 end....");
/*
并行+同步,i=0, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
并行+同步,i=1, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
并行+同步,i=2, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
....
并行+同步,i=97, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
并行+同步,i=98, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
并行+同步,i=99, currentThread: <NSThread: 0x608000079040>{number = 1, name = main}
并行队列+同步函数测试执行 end....
*/
3、串行 + 异步:开启一条新线程,按顺序执行
dispatch_queue_t q3 = dispatch_queue_create("singleQueue", NULL);
for (int i = ; i < ; i++){
dispatch_async(q3, ^{
NSLog(@"串行+异步,i=%d, currentThread: %@", i, [NSThread currentThread]);
});
}
NSLog(@"串行队列+异步函数测试执行 end....: %@", [NSThread currentThread]);
/*
串行+异步,i=0, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
串行队列+异步函数测试执行 end....: <NSThread: 0x60800007b800>{number = 1, name = main}
串行+异步,i=1, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
串行+异步,i=2, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
....
串行+异步,i=97, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
串行+异步,i=98, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
串行+异步,i=99, currentThread: <NSThread: 0x60000007f240>{number = 3, name = (null)}
*/
4、主队列 + 异步:不开启新线程,按顺序执行
dispatch_queue_t q4 = dispatch_get_main_queue();
for (int i = ; i < ; i++){
dispatch_async(q4, ^{
NSLog(@"主队列+异步,i=%d, currentThread: %@", i, [NSThread currentThread]);
});
}
NSLog(@"主队列+异步函数测试执行 end....: %@", [NSThread currentThread]);
/*
主队列+异步函数测试执行 end....: <NSThread: 0x60000006fe00>{number = 1, name = main}
主队列+异步,i=0, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
主队列+异步,i=1, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
主队列+异步,i=2, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
....
主队列+异步,i=97, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
主队列+异步,i=98, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
主队列+异步,i=99, currentThread: <NSThread: 0x60000006fe00>{number = 1, name = main}
*/
ios线程和GCD和队列同步异步的关系的更多相关文章
- ios线程和GCD
1.什么是进程? 进程是指在系统中正在运行的一个应用程序.比如同时打开QQ.Xcode,系统就会分别启动2个进程.截图 2.什么是线程? 1).一个进程要想执行任务,必须得有线程(每一个进程至少要有一 ...
- IOS多线程知识总结/队列概念/GCD/主队列/并行队列/全局队列/主队列/串行队列/同步任务/异步任务区别(附代码)
进程:正在进行中的程序被称为进程,负责程序运行的内存分配;每一个进程都有自己独立的虚拟内存空间 线程:线程是进程中一个独立的执行路径(控制单元);一个进程中至少包含一条线程,即主线程 队列 dispa ...
- iOS GCD基础篇 - 同步、异步,并发、并行的理解
1.关于GCD - GCD全称是Grand Central Dispatch - GCD是苹果公司为多核的并行运算提出的解决方案 - GCD会自动利用更多的CPU内核(比如双核.四核) - GC ...
- iOS中的GCD线程
一.什么是GCD 全称是Grand Central Dispatch ,纯C语言编写,提供非常多强大的函数,是目前苹果官网推荐的多线程开发方法,NSOperation 便是基于GCD的封装 ...
- IOS线程的一些总结
主线程的作用 (在主线程中才能设置) 显示/刷新UI界面 处理UI事件(比如点击事件.滚动事件.拖拽事件): 主线程的使用注意 别将比较耗时的操作放到主线程中. 耗时操作会卡住主线程.影响体验. [N ...
- [iOS]深入理解GCD
看到一篇很好的文章,本来想翻译的,但发现已经有人翻译了,遂简单整理了一下,方便阅读学习 新博客[wossoneri.com] 什么是GCD GCD(Grand Central Dispatch)是li ...
- [iOS]多线程和GCD
新博客wossoneri.com 进程和线程 进程 是指在系统中正在运行的一个应用程序. 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 比如同时打开QQ.Xcode,系统就会分别 ...
- iOS开发之GCD基础
重新回顾.学习GCD.Block.先贴出一篇不错的讲解GCD基础使用的文章 原文地址:http://blog.csdn.net/aolan1108/article/details/17283415 做 ...
- iOS实录:GCD使用小结(一)
导语:在iOS中,多线程方案有四种:pthread.NSThread.NSOperation & NSOperationQueue 和 GCD,但是开发中GCD使用得最多,本文主要总结一下我使 ...
随机推荐
- P3830 [SHOI2012]随机树 题解
P3830 随机树 坑题,别人的题解我看了一个下午没一个看得懂的,我还是太弱了. 题目链接 P3830 [SHOI2012]随机树 题目描述 输入输出格式 输入格式: 输入仅有一行,包含两个正整数 q ...
- html5 - history 历史管理
参考文章: w3c : http://www.w3.org/html/ig/zh/wiki/HTML5/history 张鑫旭 : http://www.zhangxinxu.com/wo ...
- ajax返回的欧洲字符(例如:法文)乱码
ajax返回值的乱码现象产生的相关代码如下: Java代码: JsonObject jsonObject = new JsonObject(); jsonObject.addProperty(&quo ...
- ActiveMQ-为什么需要消息中间件?
消息中间件的优势 UNIX的进程间通信就开始运用消息队列技术,一个进程将数据写入某个特定的队列中,其它进程可以读取队列中的数据,从而实现异步通信.对于如今的分布式系统,消息队列已经演变为独立的消息中间 ...
- lua 复制table
cocos2d-lua提供了复制方法clone(),源码如下: function clone(object) local lookup_table = {} local function _copy( ...
- JS将图片转换成Base64码
直接上代码 html页面代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- 7)django-示例(cbv)
CBV(class base view)一个url根据method方式调用相应的方法.method常用有get,post 如果是GET请求,Home类会调用get方法,如果是POST提交数据,则类会调 ...
- Codeforces 671D Roads in Yusland [树形DP,线段树合并]
洛谷 Codeforces 这是一个非正解,被正解暴踩,但它还是过了. 思路 首先很容易想到DP. 设\(dp_{x,i}\)表示\(x\)子树全部被覆盖,而且向上恰好延伸到\(dep=i\)的位置, ...
- vmware 下找不到ifcfg-eth0的问题
找不大 eth0网卡,也就连不上网络,症状是ifconfig以后只现实lo,不显示eth0 ifconfig,显示的ip是ifcfg-lo的ip 解决办法 . 拷贝cp ifcfg-lo ifcfg- ...
- 《Oracle DBA工作笔记:运维、数据迁移与性能调优》 PDF 下载
一:下载途径 二:本书图样 三:本书目录 第1篇 数据库运维篇第1章 数据库安装配置1.1 安装前的准备 11.2 安装数据库软件 51.2.1 方法1:OUI安装 61.2.2 方法2:静默安装 8 ...