资源共享
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. [uiautomator篇] python uiautomatorDemo

    #coding=utf-8 """ @version: 1.0 @author: @prerequisite: based on Python 2.7 @usage: 1 ...

  2. .NET重构(一):抽象工厂模式实现登录

    导读:一路艰辛,我也走到了重构.在重构之前,师傅让用经典三层(UI.BLL.DAL)敲了登录.用户的增删改查,共五条线.从开始对三层的朦胧,到五条线结束,终于对三层有了逻辑上清晰的理解.然后就画了几天 ...

  3. RocketMQ VS kafka

    转自:https://github.com/alibaba/RocketMQ/wiki/rmq_vs_kafka 淘宝内部的交易系统使用了淘宝自主研发的Notify消息中间件,使用MySQL作为消息存 ...

  4. OkHttpUtil

    package jp.co.gunmabank.util import android.os.Handlerimport android.os.Looperimport com.google.gson ...

  5. element-ul InputNumber 空白

    if(this.days == undefined){ this.$nextTick(function(){ this.days = 1; }); }

  6. 2016 ACM-ICPC China Finals #F Mr. Panda and Fantastic Beasts

    题目链接$\newcommand{\LCP}{\mathrm{LCP}}\newcommand{\suf}{\mathrm{suf}}$ 题意 给定 $n$ 个字符串 $s_1, s_2, \dots ...

  7. jenkins异常解答

    1.安装插件时offline 需要更换插件管理中的升级URL   http://mirror.xmission.com/jenkins/updates/current/update-center.js ...

  8. 通过new ClasspathApplicationContext("applicationContext.xml")找不到文件时

    可以把applicationContext.xml放到/WEB-INF/classes目录下使用先说:ClassPathXmlApplicationContext 这个类,默认获取的是WEB-INF/ ...

  9. Scott Mitchell的ASP.NET2.0数据指南中文版索引

    原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] 原文http://www.cnblogs.com/ilovejolly/archive/2006/10/05/52 ...

  10. 【shell】shell编程(一)-入门

    如今,不会Linux的程序员都不意思说自己是程序员,而不会shell编程就不能说自己会Linux.说起来似乎shell编程很屌啊,然而不用担心,其实shell编程真的很简单.背景 什么是shell编程 ...