简介

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

文章

不再安全的 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. 04-for循环的各个语句及list列表学习

    目录 04-for循环的各个语句及list列表学习 1. for循环 2. range()函数 3. 循环语句中的break.continue.pass 4. list列表 5. 列表生成式 6. 实 ...

  2. MySQL--索引和外键

    来自:http://www.jb51.net/article/32149.htm 1.添加PRIMARY KEY(主键索引)  ALTER TABLE `table_name` ADD PRIMARY ...

  3. atomic一定线程安全吗

    atomic只是保证了操作的原子性,原子操作即一个操作不可再分. atomic只是对读写操作进行了加锁,保证了多线程开发时一个读写操作完成之后才能进行下一个读写操作 atomic和线程安全没有太大的关 ...

  4. PAT Advanced 1154 Vertex Coloring (25) [set,hash]

    题目 A proper vertex coloring is a labeling of the graph's vertices with colors such that no two verti ...

  5. C++数组常用操作

    1. 遍历数组 使用基于范围的for循环来遍历整个数组 用_countof()来得到数组中的元素个数 #include <iostream> #include <cstdio> ...

  6. upstream实现内网网站在公网访问

    背景描述:公司内网有个网站aa.com,B部门需要访问这个aa.com,但是网站部署在内网服务器(服务器是192.168.1网段),B部门网段是192.168.100 需求描述:B部门需要访问aa.c ...

  7. 12. docker 网络 docker network (docker 网络)

    1. 环境准备 编写 Vagrantfile 为 # -*- mode: ruby -*- # vi: set ft=ruby : Vagrant.require_version "> ...

  8. jenkins-master-slave节点配置总结

    一.jenkins分布式简单介绍 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能 二.jenk ...

  9. dubbo的启动时检查

    修改的消费者(xml) 修改的消费者(注解)

  10. 好看的UI组合,为以后自己写组件库做准备

    1. 黑色格子背景 { color: rgb(255, 255, 255); text-shadow: 1px 1px 0 rgba(0,0,0,.3); rgb(62, 64, 74); backg ...