多线程安全问题及各种锁

 我来答
华源网络
2022-06-23 · TA获得超过5600个赞
知道小有建树答主
回答量:2486
采纳率:100%
帮助的人:148万
展开全部

多线程使用不当会出现资源竞争,比如多个线程同时对一块资源进行修改,就会很容易引发数据错乱和数据安全问题。

示例:
以购票系统为例,

对于多线程出现的这种问题,我们的解决办法就是使用线程同步技术,而常见的就是加锁。

2.1 OSSpinLock 自旋锁
自旋锁等待锁的线程会处于忙等(busy-wait)状态,一直占用着CPU资源。
并且现在已经不安全,可能出现优先级反转的问题。
如果等待锁的优先级较高,它会一直占用着CPU的资源,优先级低的线程就无法释放锁。
在iOS10被苹果废弃。由于已经不再安全, 这里不讨论用法了.

2.2 os_unfair_lock

导入头文件 #import <os/lock.h>

调用 ticketTest 方法
打印结果:

2.3 pthread_mutex 互斥锁

普通用法

导入头文件 #import <pthread.h>

调用 ticketTest 方法
打印结果:

mutex 也叫“互斥锁”,等待锁的线程处于休眠状态,不是忙等状态。

上面使用的是 Normal 类型同 OSSpinLock 和 os_unfair_lock 作用一样

递归用法
递归锁在被同一线程重复获取时不会产生死锁
递归类型 PTHREAD_MUTEX_RECURSIVE :

条件用法

2.4 NSLock、NSRecursiveLock
NSLock 是对 mutex 普通锁的封装
NSRecursiveLock 是对 mutex 递归锁的封装

调用 ticketTest 方法
打印结果:

NSRecursiveLock 用法与 NSLock 的用法一样。

2.5 NSCondition
NSCondition 是对 mutex 和 cond 的封装

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

2.7 dispatch_queue
直接使用GCD的串行队列,也可以实现线程同步

调用ticketTest方法
打印结果:

2.8 dispatch_semaphore
信号量的初始值可以控制线程并发访问的最大值
初始值为1时,代表同时只允许1条线程访问资源,保证线程的同步

调用otherTest会发现每隔两秒打印5条信息。

2.9 @synchronized

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

本文来自: 旺仔大包子

推荐上篇文章: iOS多线程之NSOperation的使用

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式