多线程简介
进程
线程
执行完上一个才能执行下一个
)多线程
多线程原理
多线程优缺点
程序设计更加复杂:比如线程之间的通信、多线程的数据共享
/*
参数:
1. 线程代号的地址
2. 线程的属性
3. 调用函数的指针
- void *(*)(void *)
- 返回值 (函数指针)(参数)
- void * 和 OC 中的 id 是等价的
4. 传递给该函数的参数
返回值:
如果是0,表示正确
如果是非0,表示错误码
*/
NSString *str = @"lnj";
pthread_t thid;
int res = pthread_create(&thid, NULL, &demo, (__bridge void *)(str));
if (res == 0) {
NSLog(@"OK");
} else {
NSLog(@"error %d", res);
}
NSThread
创建线程的几种方式
- detach/performSelector
+ 优点:简单快捷
+ 缺点:无法对线程进行更详细的设置
```objc
// 1.创建线程
[NSThread detachNewThreadSelector:@selector(demo:) toTarget:self withObject:@"lnj"];
// 1.创建线程
// 注意: Swift中不能使用, 苹果认为这个方法不安全
[self performSelectorInBackground:@selector(demo:) withObject:@"lnj"];
@synchronized(锁对象) { // 需要锁定的代码 }
互斥锁的优缺点 优点:能有效防止因多线程抢夺资源造成的数据安全问题 缺点:需要消耗大量的CPU资源
互斥锁注意点
原子和非原子属性
自旋锁 & 互斥锁
[self performSelectorInBackground:@selector(download) withObject:nil];
/*
waitUntilDone是否等待被调用方法执行完成,有可能也会等待调用方法的执行完成!
YES: 等待被调用线程执行完毕再执行后面的代码
NO : 不用等待被调用线程执行完毕就可以执行后面的代码
*/
[self performSelectorOnMainThread:@selector(showImage:) withObject:[UIImage imageWithData:data] waitUntilDone:YES];
GCD中有2个核心概念
执行任务
队列
注意点
各种任务队列搭配
GCD线程间通信
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行耗时的异步操作...
dispatch_async(dispatch_get_main_queue(), ^{
// 回到主线程,执行UI刷新操作
});
});
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 2秒后执行这里的代码...
});
程序运行过程中
只被执行1次 ```objc static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 只执行1次的代码(这里面默认是线程安全的) });
- 快速迭代
```objc
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
// 执行10次代码,index顺序不确定
});
不能是全局的并发队列
所有的任务都必须在一个队列中
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 执行1个耗时的异步操作
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
// 等前面的异步操作都执行完毕后,回到主线程...
});
优质内容筛选与推荐>>