iOS 中实现多线程的几种方式:
dispatch
NSOperation
performSelector
NSThread
pthread
一、dispatch,对pthread的封装
1. dispatch_sync 和 dispatch_aync
dispatch_sync 程序会等待 dispatch_sync 同步执行完成之后才能继续往下走。
dispatch_aync 程序讲任务添加到队列后继续往下执行,不必等待任务执行完成;一定不会开启新线程;以下代码会发生死锁:
// 例1:同步往当前串行队列添加任务,会产生死锁
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_sync(dispatch_get_main_queue(), ^{
});
}
2. 创建和获取队列。
获取主队列:
dispatch_get_main_queue()
获取后台队列:
// 第一个参数队列优先级,不同优先级获取到的queue不同
// #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
// 第二个参数不为0时,获取不到queue
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
创建串行队列:
dispatch_queue_t serialQueue = dispatch_queue_create("serial", NULL);
创建并发队列:
dispatch_queue_t serialQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
3. dispatch_group 等待被添加到group中的所有任务执行完毕,配合 dispatch_group_notify 或者 dispatch_group_wait。
dispatch_group_t group = dispatch_group_create();
dispatch_queue_t queue = dispatch_queue_create("queue 2", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_group_async(group, queue, ^{
NSLog(@"任务 %ld", (long)i);
});
}
dispatch_group_notify(group, queue, ^{
NSLog(@"任务执行完毕");
});
4. dispatch_after,延迟执行,一段时间后将指定的block到追加某队列中
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC);
dispatch_after(time, dispatch_get_main_queue(),^{
NSLog(@"3秒后");
});
5、dispatch_barrier_async,dispatch_barrier_async函数会等待追加到 queue 上的任务全部执行结束之后,再将指定的任务追加到该并发队列中,并且该处理执行完毕之后queue才会恢复为一般动作。
以下代码的执行顺序:
// 第一部分,并发执行
// 第二部分,barrier block 2 执行
// 第二部分,barrier block 2 执行
// 第三部分 并发执行
dispatch_queue_t queue = dispatch_queue_create("queue 2", DISPATCH_QUEUE_CONCURRENT);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
NSLog(@"任务 %ld", (long)i); // 第一部分,并发执行
});
}
// 第二部分,barrier block 1执行
dispatch_barrier_sync(queue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"dispatch_barrier_sync %ld", (long)i); // 当前线程执行
}
});
// 第二部分,barrier block 2 执行
dispatch_barrier_async(queue, ^{
for (int i = 0; i < 10; i++) {
NSLog(@"dispatch_barrier_async %ld", (long)i); // 后台线程执行
}
});
// 第三部分 并发执行
for (int i = 10; i < 20; i++) {
dispatch_async(queue, ^{
NSLog(@"任务 %ld", (long)i);
});
}
6、dispatch_semaphore,信号量,通常用与线程同步,当信号量的值小于1时候,线程进入休眠状态等待,直到dispatch_semaphore信号量大于0
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSLog(@"1");
dispatch_async(dispatch_get_global_queue(0, 0), ^{
dispatch_semaphore_signal(semaphore);
NSLog(@"2");
});
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"3");
输出顺序 1 2 3
7、dispatch_once 执行一次,通常用于实现单例
+ (instancetype)sharedInstance {
static id sharedInstance;
static dispatch_once_t once;
dispatch_once(&once, ^{
sharedInstance = [[[self class] alloc] init];
});
return sharedInstance;
}
二、NSOperation、NSOperationQueue,对NSthread的封装,更加面向对象,使用起来更加方便,可以设置任务优先级和依赖关系,控制最大执行数量 等。NSOperationQueue 在任务被添加后自动异步执行。
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:5];
for (int i = 0; i < 10; i++) {
[queue addOperation:[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"operation %ld, %@", (long)i, [NSThread currentThread]);
}]];
}
NSOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op1 %@", [NSThread currentThread]);
}];
NSOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op2 %@",[NSThread currentThread]);
}];
NSOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"op3 %@", [NSThread currentThread]);
}];
[op1 addDependency:op2];
[op2 addDependency:op3];
[queue addOperation:op2];
[queue addOperation:op3];
[queue addOperation:op1];
三、performSelectorInBackground、performSelectorOnMainThread
NSObject封装的一系列多线程方法。
[self performSelectorInBackground:@selector(operation) withObject:nil];
[self performSelectorOnMainThread:@selector(operation) withObject:nil waitUntilDone:NO];
[self performSelector:@selector(operation) onThread:[[NSThread alloc] init] withObject:nil waitUntilDone:NO];
四、NSThread
[[NSThread alloc] initWithBlock:^{
NSLog(@"任务1");
}];
[[NSThread alloc] initWithTarget:self selector:@selector(operation) object:nil];
五、pthread(POSIX threads,简称Pthreads,是线程的POSIX标准,类Unix操作系统中均使用的操作系统线程)
void *pthreadExecute(void *data) {
for (int i = 0; i < 100; i++) {
NSLog(@"pthread 执行 %ld, %@", (long)i, [NSThread currentThread]);
sleep(1);
}
return NULL;
}
- (void)pthread {
pthread_t pth;
pthread_create(&pth, NULL, pthreadExecute, NULL);
sleep(10);
pthread_cancel(pth);
NSLog(@"pthread cancel %@", [NSThread currentThread]);
}
2020-06-08 16:16:36.523342+0800 多线程[6001:678321] pthread 执行 0, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:37.524526+0800 多线程[6001:678321] pthread 执行 1, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:38.525049+0800 多线程[6001:678321] pthread 执行 2, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:39.526688+0800 多线程[6001:678321] pthread 执行 3, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:40.527975+0800 多线程[6001:678321] pthread 执行 4, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:41.533475+0800 多线程[6001:678321] pthread 执行 5, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:42.539034+0800 多线程[6001:678321] pthread 执行 6, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:43.539568+0800 多线程[6001:678321] pthread 执行 7, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:44.542963+0800 多线程[6001:678321] pthread 执行 8, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:45.544117+0800 多线程[6001:678321] pthread 执行 9, <NSThread: 0x600002ccc340>{number = 6, name = (null)}
2020-06-08 16:16:46.524624+0800 多线程[6001:678116] pthread cancel <NSThread: 0x600002c8cd40>{number = 1, name = main}
原文:https://www.cnblogs.com/beautylcy/p/13066006.html