您好!欢迎来到爱源码

爱源码

热门搜索: 抖音快手短视频下载   

线程同步的自旋锁 [源码交易]

  • 时间:2022-07-20 03:05 编辑: 来源: 阅读:290
  • 扫一扫,手机访问
摘要:线程同步的自旋锁 [源码交易]
LockMind.png是关于并发控制方案的系列文章,详细介绍了各种锁的使用和优缺点。 自旋锁os_unfair_lock互斥递归锁条件锁读写锁@synchronizedOSSpinLock、os_unfair_lock、pthread_mutex_t、pthread_cond_t和pthread_rwlock_t是值类型,不是引用类型。 这意味着使用=将制作副本,使用副本可能会导致闪回。 pthread函数认为它总是在初始化的内存地址,把它移到其他内存地址会出问题。 副本使用的OSSpinLock不会崩溃,但是会得到一个全新的锁。 如果你还不理解线程、进程、串行、并发、并行、锁等概念。,建议先看以下文章:Grand Central Dispatch的使用,OperationQueue的使用,多线程用于并发控制的简介,线程同步,无锁编程。自旋锁是一个简单、高效、线程安全的同步原语,它会反复检查锁的状态,直到它被解锁。 当锁被锁定时,大多数锁会将试图锁定的线程置于睡眠状态,然后在锁被释放时唤醒它。 这在大多数情况下是合适的,但是如果临界区域极小,时间极短,那么常规锁的睡眠和唤醒操作将变得昂贵。 此时,自旋锁的繁忙性能更高。 旋转锁使用内存屏障来保护共享资源,并且在锁定期间可能会发生抢占。 1.多线程同时访问同一资源。为了方便本系列文章其余的锁,首先创建一个需要线程同步的基类,每次锁细节的时候都可以从这个基类继承。 class base demo { private var tickets count = 25 private var Money = 100//MARK:-Money func Money test(){ let queue = dispatch queue . global(QoS:。实用程序)queue.async { for _ in 1...10 { self . save money()} } queue . async { for _ in 1...10 { self . draw money()} } } Fundrawmoney(){ var Old money = money sleep(1)Old money-= 20 money = Old money print("取20元,还剩一些\ (oldMoney)元-\(thread . current)")} func save money(){ var Old money = money sleep(1)Old money+= 50 money = Old money print("存入50元,还剩\(oldMoney)元-\ (Thread.current)") } // MARK: -销售票func ticketTest() { let实用程序)queue.async { for _ in 1...5 { self . sale ticket()} } queue . async { for _ in 1...5 { self . sale ticket()} } queue . async { for _ in 1...5 { self . sale ticket()} } } func sale ticket(){ var oldTicketsCount = ticketsCount sleep(1)oldTicketsCount-= 1 ticketsCount = oldTicketsCount print("还剩\(oldTicketsCount)张票-\(thread . current)")} funcothertest(){ } }即使执行i = i +1这样简单的命令,也可以分为三条指令:读取I的值, I的值加1。 将值写入I。 当执行上述任何指令时,可能发生上下文切换,或者多个线程可能同时运行。 比如线程A读取I的值,线程B同时读取I的值。加一个后,线程A写,线程B写。 这将导致I的值仅增加一次。 为了解决这个问题,我们应该采取线程同步措施。 调用moneyTest()和ticketTest()函数时,会触发并发存取款和售票,会产生意想不到的结果。 后续部分只需要在调用基类方法时加锁和解锁即可。 2.自旋锁API2.1初始化OSSpinLockOSSpinLock为数值型,解锁值为零,锁定值非零。 使用以下代码创建OSSpinLock属性:private var money lock:OSSpinLock = OS _ spin lock _ init private var ticket lock:OSSpinLock = OS _ spin lock _ init。如果在Objective-C中使用自旋锁,则需要导入# import < lib kern/osatomic . h & gt;头文件 2.2锁定OSSpinLockLock() OSSpinLockTry()锁定时调用OSSpinLockLock()和OSSpinLockTry()。 如果锁已经被锁定,OSSpinLockLock()函数会忙于等待,也会采用少量策略避免优先级反转,但对于执行时间长、竞争激烈的任务效率较低。 如果锁已被锁定,OSSpinLockTry()将立即返回false,并且不会等待。 锁定方法如下:OS _ fair _ lock _ lock(& money lock)2.3解锁OSSpinLockUnlock()解锁时调用OSSpinLockUnlock()函数。 OS _ fair _ lock _ unlock(& amp;MoneyLock)升级后的文件OSSpinLockDemo.swift如下:class osspinlockdemo:base demo { private var money lock:osspinlock = OS _ spin lock _ init private var ticket lock:osspinlock。= OS _ spin lock _ INIT override func draw money(){ OSSpinLockLock(& amp;money lock)super . draw money()osspinlock unlock(& amp;money lock)} override func save money(){ OSSpinLockLock(& amp;money lock)super . save money()osspinlock unlock(& amp;money lock)} override func sale ticket(){ OSSpinLockLock(& amp;ticket lock)super . sale ticket()osspinlock unlock(& amp;TicketLock) }}锁解锁时,执行结果可能是错误的;锁定后反复执行,结果都是正确的。 3.自旋锁性能当条件合适时,自旋锁性能最佳。 旋转锁的问题是,当一个线程持有锁时,其余试图锁定锁的线程将浪费CPU资源。 如果临界面积很小,一般没有问题。 如果一个线程锁定,而没有其他线程试图获取该锁,就不会有问题。 如果其余的线程也试图获取锁,它们必须等待持有锁的线程完成执行。 在单核设施中,这个问题更加突出。 因为持有锁的线程必须等待旋转的线程用完分配的时间片才能执行 也可以采取一些措施来减少这些问题。 例如,计算旋转数,当旋转数为正时,将资源交给调度程序。 OSSpinLock实现了一些类似的策略,在大多数情况下,OSSpinLock工作得很好,甚至避免了优先级反转。 4.优先级反转优先级反转是指低优先级线程持有锁,高优先级线程被锁阻塞,或者等待低优先级线程的执行结果。 在传统的锁中,只有高优先级线程必须等待低优先级线程执行,因为低优先级线程分配的资源较少,并且可能必须等待很长时间。 但是在自旋锁中,这个问题更严重。 因为等待锁的高优先级线程在等待的时候不停的旋转,占用CPU资源,低优先级线程被分配的资源更少,进一步导致锁长时间得不到释放。 OSSpinLock将采用一些策略来缓解优先级反转的问题。 例如,如果在旋转确认次数之后,锁定线程的进度没有变化,则旋转停止。 调度队列和pthread mutex通过自动增加持有锁的线程的优先级来处理优先级反转。 因为信号量(例如dispatch_semaphore_t)不知道哪个线程正在执行工作,所以它不会做出类似的解决方案。 服务质量(QOS)是在iOS内核更新后推出的。 QOS允许NSOperation、NSThread、dispatch queue和pthread将任务划分为不同的优先级。 具有高QOS的线程永远不会衰减到低QOS,调度程序将始终优先为具有高QOS的线程分配资源。 因此,纺纱QOS线程将保持忙碌等。,持有锁的低QOS线程无法获得执行任务的资源,导致旋转锁不再安全。 所以iOS 10把OSSpinLock换成了os _ unfair _ lock。 下一篇文章将详细介绍os _ unfair _ lock。 演示名称:同步源地址:pro 648/basicdemos-IOs/tree/MASTER/synchron ization下一篇:OS _ unfair _ lock of Thread synchron ization参考:spinlock为什么自旋锁对iolock、线程安全、Swift不好欢迎更多指正:pro648/tips本文地址:pro 648/TIPS/BLOB/MASTER/SOURCES/% E7 % BA % BF % E7 % A8 % 8b % E5 % 90% 8c % E6 % AD % A5 % E4 % B9 % 8b % E8


  • 全部评论(0)
资讯详情页最新发布上方横幅
最新发布的资讯信息
【域名/主机/服务器|】qq邮箱提醒在哪里打开(2024-06-04 18:58)
【技术支持|常见问题】1556原创ng8文章搜索页面不齐(2024-05-01 14:43)
【技术支持|常见问题】1502企业站群-多域名跳转-多模板切换(2024-04-09 12:19)
【技术支持|常见问题】1126完美滑屏版视频只能显示10个(2024-03-29 13:37)
【技术支持|常见问题】响应式自适应代码(2024-03-24 14:23)
【技术支持|常见问题】1126完美滑屏版百度未授权使用地图api怎么办(2024-03-15 07:21)
【技术支持|常见问题】如何集成阿里通信短信接口(2024-02-19 21:48)
【技术支持|常见问题】算命网微信支付宝产品名称年份在哪修改?风水姻缘合婚配对_公司起名占卜八字算命算财运查吉凶源码(2024-01-07 12:27)
【域名/主机/服务器|】帝国CMS安装(2023-08-20 11:31)
【技术支持|常见问题】通过HTTPs测试Mozilla DNS {免费源码}(2022-11-04 10:37)

联系我们
Q Q:375457086
Q Q:526665408
电话:0755-84666665
微信:15999668636
联系客服
企业客服1 企业客服2 联系客服
86-755-84666665
手机版
手机版
扫一扫进手机版
返回顶部