容易混淆的术语
有4个术语比较容易混淆:同步、异步、并发、串行
同步和异步主要影响:能不能开启新的线程
同步:在当前线程中执行任务,不具备开启新线程的能力
异步:在新的线程中执行任务,具备开启新线程的能力 (例如丢在主线程中并不会开启新的线程)
dispatch_queue_t queue = dispatch_get_main_queue();
dispatch_async(queue, ^{
NSLog(@"当前线程:%@",[NSThread currentThread]);
});
打印结果:
当前线程:<NSThread: 0x282459500>{number = 1, name = main}
并发和串行主要影响:任务的执行方式
并发:多个任务并发(同时)执行
串行:一个任务执行完毕后,再执行下一个任务
多线程造成死锁的原因
使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列(产生死锁)
如下示例。
viewdidLoad本身就是在mainQueue主线程中执行代码,这时候sync同步添加任务到到当前mainQueue中。所以就卡死,程序崩溃。
GNUstep是GNU计划的项目之一,它将Cocoa的OC库重新开源实现了一遍 源码地址:http://www.gnustep.org/resources/downloads.php 虽然GNUstep不是苹果官方源码,但还是具有一定的参考价值
多线程同步方案
性能从上到下:
iOS中的读写安全方案
多读单写方案:
思考如何实现以下场景
同一时间,只能有1个线程进行写的操作
同一时间,允许有多个线程进行读的操作
同一时间,不允许既有写的操作,
又有读的操作 上面的场景就是典型的“多读单写”,经常用于文件等数据的读写操作,iOS中的实现方案有
pthread_rwlock:读写锁
dispatch_barrier_async:异步栅栏调用
1.pthread_rwlock:
2.dispatch_barrier_async
使用注意:
这个函数传入的并发队列必须是自己通过dispatch_queue_cretate创建的 如果传入的是一个串行或是一个全局的并发队列,那这个函数便等同于dispatch_async函数的效果