iOS数据锁
简介
当一个线程访问数据时,而其他数据不能进行访问,保证线程安全或者可以理解为执行多线程,对于共享资源访问时保证互斥的要求
文章
iOS多线程篇-NSThread-synchronized(互斥锁)
分类
1.自旋锁:是用于多线程同步的一种锁,线程反复检查锁变量是否可用(一直进行do while忙等)
2.信号量:可以有更多的取值空间,用来实现更加复杂的同步,而不单单是线程间互斥
3.互斥锁:是一种用于多线程编程中,防止两条线程同时对同一公共资源(比如全局变量)进行读写的机制
4.条件锁:当进程的某些资源要求不满足时就进入休眠,也就是锁住了。当资源被分配到了,条件锁打开,进程继续运行
5.递归锁:在同一线程上该锁是可重入的,对于不同线程则相当于普通的互斥锁
6.读写锁:对共享资源的访问者划分成读者和写者,读者只对共享资源进行读访问,写者则需要对共享资源进行写操作
OSSpinLock
- (void)osspinlock:(int)count{
NSTimeInterval begin, end;
OSSpinLock lock = OS_SPINLOCK_INIT;
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
OSSpinLockLock(&lock);
OSSpinLockUnlock(&lock);
}
end = CACurrentMediaTime();
printf("OSSpinLock: %8.2f msn", (end - begin) * 1000);
}
os_unfair_lock(iOS10之后替代OSSPinLock的锁,解决了优先级反转的问题)
- (void)os_unfair_lock:(int)count{
if (@available(iOS 10.0, *)) {
NSTimeInterval begin, end;
os_unfair_lock_t unfairLock;
unfairLock = &(OS_UNFAIR_LOCK_INIT);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
os_unfair_lock_lock(unfairLock);
os_unfair_lock_unlock(unfairLock);
}
end = CACurrentMediaTime();
printf("os_unfair_lock: %8.2f msn", (end - begin) * 1000);
}
}
信号量
dispatch_semaphore
- (void)dispatch_semaphore:(int)count{
NSTimeInterval begin, end;
dispatch_semaphore_t lock = dispatch_semaphore_create(1);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
dispatch_semaphore_wait(lock, DISPATCH_TIME_FOREVER);
dispatch_semaphore_signal(lock);
}
end = CACurrentMediaTime();
printf("dispatch_semaphore: %8.2f msn", (end - begin) * 1000);
}
互斥锁
NSLock
- NSLock是最常使用的互斥锁,遵循NSLocking协议,通过lock和unlock来完成锁定和解锁*
- (void)nslock:(int)count{
NSTimeInterval begin, end;
NSLock *lock = [NSLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
printf("NSLock: %8.2f msn", (end - begin) * 1000);
}
pthread_mutex
- (void)pthread_mutex:(int)count{
NSTimeInterval begin, end;
pthread_mutex_t lock;
pthread_mutex_init(&lock, 大专栏 iOS数据锁NULL);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
end = CACurrentMediaTime();
pthread_mutex_destroy(&lock);
printf("pthread_mutex: %8.2f msn", (end - begin) * 1000);
}
synchronized
- (void)synchronized:(int)count{
NSTimeInterval begin, end;
NSObject *lock = [NSObject new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
@synchronized(lock) {}
}
end = CACurrentMediaTime();
printf("@synchronized: %8.2f msn", (end - begin) * 1000);
}
条件锁
NSCondition
- (void)_NSCondition:(int)count{
NSTimeInterval begin, end;
NSCondition *lock = [NSCondition new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
printf("NSCondition: %8.2f msn", (end - begin) * 1000);
}
NSConditionLock
- (void)_NSConditionLock:(int)count{
NSTimeInterval begin, end;
NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition:1];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
printf("NSConditionLock: %8.2f msn", (end - begin) * 1000);
}
递归锁
NSRecursiveLock
- (void)_NSRecursiveLock:(int)count{
NSTimeInterval begin, end;
NSRecursiveLock *lock = [NSRecursiveLock new];
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
[lock lock];
[lock unlock];
}
end = CACurrentMediaTime();
printf("NSRecursiveLock: %8.2f msn", (end - begin) * 1000);
}
pthread_mutex_recursive
- (void)pthread_mutex_recursive:(int)count{
NSTimeInterval begin, end;
pthread_mutex_t lock;
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&lock, &attr);
pthread_mutexattr_destroy(&attr);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_mutex_lock(&lock);
pthread_mutex_unlock(&lock);
}
end = CACurrentMediaTime();
pthread_mutex_destroy(&lock);
printf("pthread_mutex(recursive): %8.2f msn", (end - begin) * 1000);
}
读写锁
pthread_rwlock
- (void)pthread_rwlock:(int)count{
NSTimeInterval begin, end;
pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock,NULL);
begin = CACurrentMediaTime();
for (int i = 0; i < count; i++) {
pthread_rwlock_rdlock(&rwlock);
pthread_rwlock_unlock(&rwlock);
}
end = CACurrentMediaTime();
printf("pthread_rwlock: %8.2f msn", (end - begin) * 1000);
}
总结
通过各种常见锁介绍和性能评测,可以看出要是没有优先级反转的问题的话,osspinlock为最优,其次就是dispatch_semaphore,dispatch_semaphore和os_unfair_lock差距很小,然后就是pthread_mutex。
代码下载
iOS数据锁的更多相关文章
- iOS数据持久化-OC
沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...
- Delphi IOS 蓝牙锁屏后台运行
Delphi IOS 后台运行 同样的程序,编译成android,锁屏后继续运行正常,蓝牙通讯正常,但在IOS下锁屏后程序的蓝牙就中断通讯了? IOS的机制就是这样,锁屏就关闭了. 音乐播放器是怎么做 ...
- iOS数据持久化方式及class_copyIvarList与class_copyPropertyList的区别
iOS数据持久化方式:plist文件(属性列表)preference(偏好设置)NSKeyedArchiver(归档)SQLite3CoreData沙盒:iOS程序默认情况下只能访问自己的程序目录,这 ...
- iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)
本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...
- iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver
IOS数据持久化的方式分为三种: 属性列表 (plist.NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等 归档(又名 ...
- iOS数据存储之对象归档
iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...
- iOS数据存储之属性列表理解
iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...
- iOS数据本地化
本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...
- IOS数据持久化之归档NSKeyedArchiver
IOS数据持久化的方式分为三种: 属性列表 (自定义的Property List .NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data ...
随机推荐
- Ubuntu Teamviewer安装使用
关于Ubuntu环境下teamviewer的安装(亲测可用-) 以下内容均转自:https://blog.csdn.net/weixin_41887832/article/details/798329 ...
- idea指定启动参数、环境变量
1. 点击Edit Configurations 2 # VM Arguments 是设置的虚拟机的属性 # VM options # 环境变量参数 这里需要指定-D参数 -server -XX:M ...
- uploadifive使用笔记
官网地址:http://www.uploadify.com/ uploadifive 是基于H5开发,所以支持移动端和PC端 <input type="file" name= ...
- c# 之Enum--枚举
枚举 收藏的博文连接 枚举类型声明为一组相关的符号常数定义了一个类型名称.枚举用于“多项选择”场合,就是程序运行时从编译时已经设定的固定数目的“选择”中做出决定. 枚举类型(也称为枚举):该类型可以 ...
- 01 语言基础+高级:1-10 JDK8新特性_day12【函数式接口】
day12[函数式接口] 主要内容自定义函数式接口函数式编程常用函数式接口 教学目标能够使用@FunctionalInterface注解能够自定义无参无返回函数式接口能够自定义有参有返回函数式接口能够 ...
- Java搭建WebSocket的两种方式
下面分别介绍搭建方法:一.直接使用Java EE的api进行搭建.一共3个步骤:1.添加依赖<dependency> <groupId>javax</groupId ...
- react-native屏幕适配
写一个屏幕适配类文件AdapterUtil.js,这样避免每次进行单位换算 "use strict" import {Dimensions, StatusBar, Platform ...
- 嵌入式linux学习笔记
1.溢出:两个数相加,如果最高位的进位和此高位的进位不同,则产生溢出. 2.进位和溢出的概念不一样. 3.预取(取得是编译后得到的机器代码)-->译码-->执行 4.ARM的汇编指令长度是 ...
- 小白学习之pytorch框架(6)-模型选择(K折交叉验证)、欠拟合、过拟合(权重衰减法(=L2范数正则化)、丢弃法)、正向传播、反向传播
下面要说的基本都是<动手学深度学习>这本花书上的内容,图也采用的书上的 首先说的是训练误差(模型在训练数据集上表现出的误差)和泛化误差(模型在任意一个测试数据集样本上表现出的误差的期望) ...
- Faraday Future,FF2019年一季度前完成第一阶段5亿美元左右的A+轮融资,2019年年底前完成7亿美元的Pre-IPO轮融资,2020IPO
FF2019年一季度前完成第一阶段5亿美元左右的A+轮融资,2019年年底前完成7亿美元的Pre-IPO轮融资,2020IPO 区块链公司先行宣布将对FF进行投资.EVAIO(中文名:伊娃)公司 跨链 ...