简介

当一个线程访问数据时,而其他数据不能进行访问,保证线程安全或者可以理解为执行多线程,对于共享资源访问时保证互斥的要求

文章

不再安全的 OSSpinLock

iOS开发中的11种锁以及性能对比

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。

代码下载

TJLock


iOS数据锁的更多相关文章

  1. iOS数据持久化-OC

    沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...

  2. Delphi IOS 蓝牙锁屏后台运行

    Delphi IOS 后台运行 同样的程序,编译成android,锁屏后继续运行正常,蓝牙通讯正常,但在IOS下锁屏后程序的蓝牙就中断通讯了? IOS的机制就是这样,锁屏就关闭了. 音乐播放器是怎么做 ...

  3. iOS数据持久化方式及class_copyIvarList与class_copyPropertyList的区别

    iOS数据持久化方式:plist文件(属性列表)preference(偏好设置)NSKeyedArchiver(归档)SQLite3CoreData沙盒:iOS程序默认情况下只能访问自己的程序目录,这 ...

  4. iOS 数据持久化(扩展知识:模糊背景效果和密码保护功能)

    本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...

  5. iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver

    IOS数据持久化的方式分为三种: 属性列表 (plist.NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data.第三方类库等 归档(又名 ...

  6. iOS数据存储之对象归档

    iOS数据存储之对象归档 对象归档 对象归档是iOS中数据持久化的一种方式. 归档是指另一种形式的序列化,但它是任何对象都可以实现的更常规的类型.使用对模型对象进行归档的技术可以轻松将复杂的对象写入文 ...

  7. iOS数据存储之属性列表理解

    iOS数据存储之属性列表理解 数据存储简介 数据存储,即数据持久化,是指以何种方式保存应用程序的数据. 我的理解是,开发了一款应用之后,应用在内存中运行时会产生很多数据,这些数据在程序运行时和程序一起 ...

  8. iOS数据本地化

    本篇随笔除了介绍 iOS 数据持久化知识之外,还贯穿了以下内容: (1)自定义 TableView,结合 block 从 ViewController 中分离出 View,轻 ViewControll ...

  9. IOS数据持久化之归档NSKeyedArchiver

    IOS数据持久化的方式分为三种: 属性列表 (自定义的Property List .NSUserDefaults) 归档 (NSKeyedArchiver) 数据库 (SQLite.Core Data ...

随机推荐

  1. [极客大挑战 2019]Secret File

    0x00知识点 没有过滤file 使用php的file伪协议去读取文件 ?file=php://filter/convert.base64-encode/resource=flag.php 0x01解 ...

  2. vue项目开始 首页 part1

    stylus 优点:css之中使用一些变量,方便我们快速编写css 项目中我们使用css开发的辅助工具帮助我们开发网站样式 安装:终端打开我们项目的文件夹 npm install stylus --s ...

  3. linux目录和安装目录学习

    我一般会在/opt目录下创建 一个software目录,用来存放我们从官网下载的软件格式是.tar.gz文件,或者通过 wget+地址下载的.tar.gz文件 执行解压缩命令,这里以nginx举例 t ...

  4. Windows下将Python源代码.py文件封装成exe可执行文件方法

    安装pyinstaller cmd中使用pip安装 pip install pyinstaller 同时会自动安装pywin32(pip真慢50M这里就走20KB),可以进行切换为国内源进行提速. 就 ...

  5. linux的/dev内容介绍

    http://www.cnblogs.com/lidabo/p/4505360.html 这个结合那个linux的终端介绍 https://zhidao.baidu.com/question/1742 ...

  6. 01 语言基础+高级:1-3 常用API第一部分_day07【Scanner类、Random类、ArrayList类】

    day07[Scanner类.Random类.ArrayList类] Scanner类Random类ArrayList类 教学目标 能够明确API的使用步骤能够使用Scanner类获得键盘录入数据能够 ...

  7. python学习笔记-字符串的拼接

    1.百分号方式拼接 %[(name)][flags][width].[precision]typecode (name)      可选,用于选择指定的key flags          可选,可供 ...

  8. Python—使用Json序列化Datetime类型

    import json from datetime import datetime, date """ str,int,list,tuple,dict,bool,None ...

  9. Maven--设置Http代理

    <settings> ... <proxies> <proxy> <id>my-proxy</id> <active>true& ...

  10. linux服务器开放防火墙和端口,以及查询状态

    自己搞一个自己网站时候,购买的阿里云服务器,发现部署项目访问不到,首先需要确认入站规则是否配置. 一.安全组列表添加 1.打开安全组列表 2.添加入站规则 3.添加安全组规则 二.通过防火墙,开启端口 ...