资源共享
1块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源
比如多个线程访问同一个对象、同一个变量、同一个文件
当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题
 
一、解决方案
解决方案:使用线程同步技术(同步,就是协同步调,按预定的先后次序进行)
常见的线程同步技术是:加锁
 
1、OSSpinLock
OSSpinLock叫做”自旋锁”,等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源

目前已经不再安全,可能会出现优先级反转问题
如果等待锁的线程优先级较高,它会一直占用着CPU资源,优先级低的线程就无法释放锁
需要导入头文件#import<libkern/OSAtomic.h>
 

2、os_unfair_lock
os_unfair_lock用于取代不安全的OSSpinLock,从iOS10开始才支持
从底层调用看,等待os_unfair_lock锁的线程会处于休眠状态,并非忙等
需要导入头文件#import<os/lock.h>

 
3、pthread_mutex
mutex叫做”互斥锁”,等待锁的线程会处于休眠状态
需要导入头文件#import<pthread.h>
 
pthread_mutex–普通锁

 
pthread_mutex–递归锁
 
pthread_mutex–条件

 
4、NSLock
NSLock是对mutex普通锁的封装

 
5、NSRecursiveLock

NSRecursiveLock也是对mutex递归锁的封装,API跟NSLock基本一致

6、NSCondition
NSCondition是对mutex和cond的封装

7、NSConditionLock
NSConditionLock是对NSCondition的进一步封装,可以设置具体的条件值

8、dispatch_semaphore
semaphore叫做”信号量”
信号量的初始值,可以用来控制线程并发访问的最大数量
信号量的初始值为1,代表同时只允许1条线程访问资源,保证线程同步

9、dispatch_queue(DISPATCH_QUEUE_SERIAL)
 直接使用GCD的串行队列,也是可以实现线程同步的

 
10、@synchronized
@synchronized是对mutex递归锁的封装
源码查看:objc4中的objc-sync.mm文件(苹果源码官方地址)
@synchronized(obj)内部会生成obj对应的递归锁,然后进行加锁、解锁操作

二、iOS线程同步方案性能比较

原则:
  普通锁比递归锁性能好
  语言越高级,封装的逻辑越多,性能也就越差(所有语言都如此) 
  实际测试
 
性能从高到低排序
os_unfair_lock   // 缺点:iOS10才支持  
OSSpinLock  // 缺点:可能出现优先级反转 已经不再安全 苹果也不推荐使用
dispatch_semaphore // 推荐使用 
pthread_mutex  // 优点:跨平台 互斥锁(普通锁) 推荐使用
dispatch_queue(DISPATCH_QUEUE_SERIAL) // c
NSLock     // oc
NSCondition   // oc
pthread_mutex(recursive) // 递归锁
NSRecursiveLock  // oc
NSConditionLock   // oc
@synchronized // 递归锁 oc

三、自旋锁、互斥锁 选择

自旋锁:等待状态处于忙等
互斥锁:等待状态处于休眠
 
1、什么情况使用自旋锁比较划算?
预计线程等待锁的时间很短
加锁的代码(临界区)经常被调用,但竞争情况很少发生
CPU资源不紧张
多核处理器
 
2、什么情况使用互斥锁比较划算?
预计线程等待锁的时间较长
单核处理器
临界区有IO操作
临界区代码复杂或者循环量大
临界区竞争非常激烈

四、读写锁

 场景:
同一时间,只能有1个线程进行写的操作
同一时间,允许有多个线程进行读的操作
同一时间,不允许既有写的操作,又有读的操作
 
 上面的场景就是典型的“多读单写”,经常用于文件等数据的读写操作,iOS中的实现方案有:
1、读写锁:pthread_rwlock

等待锁的线程会进入休眠

2、dispatch_barrier_async

这个函数传入的并发队列必须是自己通过dispatch_queue_cretate创建的

如果传入的是一个串行或是一个全局的并发队列,那这个函数便等同于dispatch_async函数的效果

iOS开发——高级篇——多线程的安全隐患的更多相关文章

  1. iOS开发——高级篇——多线程dispatch_apply

    我们知道遍历数组是一个相对耗时的操作,而同时手机的核是越来越多,所以我们需要充分利用iOS多核的作用. 特别是在遍历操作中还有其他耗时操作.像我们平时直接遍历数组的操作 ,i< ,i++){ / ...

  2. iOS开发——高级篇——多线程GCD死锁

    面试题 请问以下代码打印结果: - (void)interview01 { // 以下代码是在主线程执行的 NSLog(@"执行任务1"); dispatch_queue_t qu ...

  3. iOS开发网络篇—多线程断点下载

    iOS开发网络篇—多线程断点下载 说明:本文介绍多线程断点下载.项目中使用了苹果自带的类,实现了同时开启多条线程下载一个较大的文件.因为实现过程较为复杂,所以下面贴出完整的代码. 实现思路:下载开始, ...

  4. iOS开发——高级篇——iOS开发之网络安全密码学

    一.非对称加密 - RSA : + 公钥加密,私钥解密: + 私钥加密,公钥解密: + 只能通过因式分解来破解 二.对称加密 - DES - 3DES - AES (高级密码标准,美国国家安全局使用, ...

  5. iOS开发——高级篇——线程同步、线程依赖、线程组

    前言 对于iOS开发中的网络请求模块,AFNet的使用应该是最熟悉不过了,但你是否把握了网络请求正确的完成时机?本篇文章涉及线程同步.线程依赖.线程组等专用名词的含义,若对上述名词认识模糊,可先进行查 ...

  6. iOS开发——高级篇——iPad开发、iPad开发中的modal

    一.iPad简介 1.什么是iPad一款苹果公司于2010年发布的平板电脑定位介于苹果的智能手机iPhone和笔记本电脑产品之间跟iPhone一样,搭载的是iOS操作系统 2.iPhone和iPadi ...

  7. iOS开发——高级篇——地理定位 CoreLocation

    一.CoreLocation 在移动互联网时代,移动app能解决用户的很多生活琐事,比如周边:找餐馆.找KTV.找电影院等等导航:根据用户设定的起点和终点,进行路线规划,并指引用户如何到达 在上述应用 ...

  8. iOS开发——高级篇——地图 MapKit

    一.简介 1.在移动互联网时代,移动app能解决用户的很多生活琐事,比如周边:找餐馆.找KTV.找电影院等等导航:根据用户设定的起点和终点,进行路线规划,并指引用户如何到达 在上述应用中,都用到了定位 ...

  9. iOS开发——高级篇——iOS 项目的目录结构

    最近闲来无事去面试一下iOS开发,让我感到吃惊的,面试官竟然问怎么分目录结构,还具体问每个子目录的文件名. 目录结构确实非常重要,面试官这么问,无疑是想窥探开发经验.清晰的目录结构,可让人一眼明白相应 ...

随机推荐

  1. ER模型图工具:PowerDesigner

    导读:开始是想一个阶段一个阶段的写文档,再写了可行性分析报告之后,发现这种方法整体性不强,写出来的文档也总是有考虑不周的地方.后来,就看完了全部的软工视频再写.现在该写项目开发总结报告了.在写文档的过 ...

  2. 【UML】UML图的发展和体系结构

    导读:上次给徒弟验收UML的项目,在验收的时候提出了很多问题,徒弟也暴露了一些问题.说好我们一起总结成长的,由于最近的事儿,比较忙,所以现在进行总结.上次会议中说到要用门卫思维去总结这部分的知识点,用 ...

  3. Codeforces Round #402 (Div. 2) A+B+C+D

    Codeforces Round #402 (Div. 2) A. Pupils Redistribution 模拟大法好.两个数列分别含有n个数x(1<=x<=5) .现在要求交换一些数 ...

  4. 算法复习——迭代加深搜索(骑士精神bzoj1085)

    题目: Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相 ...

  5. Hibernate批量更新和批量删除批量添加(转)

    通常,在一个Session对象的缓存中只存放数量有限的持久化对象,等到Session对象处理事务完毕,还要关闭Session对象,从而及时释放Session的缓存占用的内存.批量处理数据是指在一个事务 ...

  6. 【CCF】行车路线 改编Dijkstra

    [AC] #include<iostream> #include<cstdio> #include<string> #include<cstring> ...

  7. Spoj-ANTP Mr. Ant & His Problem

    Mr. Ant has 3 boxes and the infinite number of marbles. Now he wants to know the number of ways he c ...

  8. 【BZOJ1500】维修数列(splay)

    题意: 输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目.第2行包含N个数字,描述初始时的数列.以下M行,每行一条命令,格式参见问题描述中的 ...

  9. 在echars上发布的半圆环形图

    http://gallery.echartsjs.com/editor.html?c=xBJvoMcPfz&v=1

  10. javascript实现数据结构----栈

    //栈是一种遵从后进先出原则的有序集合. //新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底 //在栈里,新元素都靠近栈顶,旧元素都叫做栈底 function Stack(){ va ...