iOS/Mac开发中各种锁的使用

  1. NSRecursiveLock递归锁

    所谓递归锁,就是在同一线程上该锁是可重入的,它对于不同线程相当于普通的互斥锁。NSRecursiveLock类定义的锁可以在同一线程多次lock,而不会造成死锁。递归锁会跟踪它被多少次lock。每次成功的lock都必须平衡调用unlock操作。只有所有的锁住和解锁操作都平衡的时候,锁才真正被释放给其他线程获得。

NSRecursiveLock *lock = [[NSRecursiveLock alloc] init];
//开一个线程
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        static void (^RecursiveMethod)(int);
        RecursiveMethod = ^(int value) {
            [lock lock];       //启动递归锁
            if (value > 0) {
                NSLog(@"value = %d", value);
                sleep(2);
                RecursiveMethod(value - 1);
            }
            [lock unlock];    //关闭递归锁
        };
        RecursiveMethod(5);
    });
//再开一个线程dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        sleep(2);
        //判断当前锁的状态
        BOOL flag = [lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:1]];
        if (flag) {
            NSLog(@"lock before date");
            [lock unlock];
        } else {
            NSLog(@"fail to lock before date");
        }
    });

代码分析:第一个异步dispatch创建了一个新的线程,并加入了递归锁,此时,在第二个异步dispatch创建的新线程中,判断当前的递归锁的状态。

2. NSConditionLock条件锁

普通的互斥锁和递归锁都只考虑锁和解锁的问题,这样的锁无法满足多线程对访问共享资源的各种需求。因此,条件锁(NSConditionLock)的出现可以解决多线程技术中需要满足特定条件才能解开某些锁的场景。

//主线程中
NSConditionLock *conditionLock = [[NSConditionLock alloc] init];

//异步线程1    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        for (int i=0;i<=2;i++)
        {
            //创建一个不需要条件的锁
            [conditionLock lock];
            NSLog(@"thread1:%d",i);
            sleep(2);
            [conditionLock unlockWithCondition:i];
        }
    });

//异步线程2
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //设置一个条件锁,需要对应的unlockWithCondition:2才能解开
        [conditionLock lockWhenCondition:2];
        NSLog(@"thread2");
        [conditionLock unlock];
 });

代码分析:异步线程1创建了一个没有开锁条件的条件锁,而异步线程2并发的创建了一个开锁条件为2的条件锁,当线程1中的循环变量i=2时,线程2中的条件锁被解开。

3. NSDistributedLock分布式锁

对于多个进程或多个程序之间需要构建互斥的场景时,使用上述多线程间的锁就无法满足需求。此时,需要使用到分布式锁。分布式锁是通过文件系统实现的,它不继承自NSLock,因而也没有实现lock方法,但它提供了tryLock,unlock,breakLock等方法,如果需要lock,则必须自己实现一个trylock的轮询。

应用A:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//进程间互斥所用的锁
NSDistributedLock  *lock = [[NSDistributedLock alloc] initWithPath:@"/Users/mac/Desktop/earning__"];
  [lock breakLock];
        [lock tryLock];
        sleep(10);
        [lock unlock];
        NSLog(@"appA: OK");
    });

应用B:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
       NSDistributedLock *lock = [[NSDistributedLock alloc] initWithPath:@"/Users/mac/Desktop/earning__"];
        while (![lock tryLock]) {
            NSLog(@"appB: waiting");
            sleep(1);
        }
        [lock unlock];
        NSLog(@"appB: OK");
    });

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-03 22:25:13

iOS/Mac开发中各种锁的使用的相关文章

中文 iOS/Mac 开发博客列表(网址改进)

中文 iOS/Mac 开发博客列表(网址改进) https://github.com/tangqiaoboy/iOSBlogCN 大牛blog: http://blog.devtang.com/ 唐巧 网易微博后台 .猿题库.有道云笔记.粉笔网 http://beyondvincent.com/blog/archives/ 破船 http://onevcat.com/ 王巍 Line 技术领域 :ios+unity3d http://swifter.tips 王巍 swifter 的网站 htt

iOS/mac开发的一些知名个人博客

王巍的博客:王巍目前在日本横滨任职于LINE.工作内容主要进行Unity3D开发,8小时之外经常进行iOS/Mac开发.他的陈列柜中已有多款应用,其中番茄工作法工具非常棒.http://onevcat.com池 建强的博客: 池建强,70后程序员,Blogger.98年毕业,先后就职于洪恩软件.RocketSofeware和用友软件工程公司(后更名为瑞友 科技),现任瑞友科技IT应用研究院副院长.该博客最初每天发送一条Mac技巧,不过目前已经形成了一种技术和人文结合的风格,时而随笔,时而技术.h

中文 iOS/Mac 开发博客列表

中文 iOS/Mac 开发博客列表 博客地址 RSS地址 OneV's Den http://onevcat.com/atom.xml 破船之家 http://beyondvincent.com/atom.xml NSHipster http://nshipster.cn/feed.xml Limboy 无网不剩 http://feeds.feedburner.com/lzyy 唐巧的技术博客 http://blog.devtang.com/atom.xml Lex Tang http://le

深入理解 iOS 开发中的锁

来源:伯乐在线 - 夏天然后 链接:http://ios.jobbole.com/89474/ 点击 → 申请加入伯乐在线专栏作者 摘要 本文的目的不是介绍 iOS 中各种锁如何使用,一方面笔者没有大量的实战经验,另一方面这样的文章相当多,比如 iOS中保证线程安全的几种方式与性能对比.iOS 常见知识点(三):Lock.本文也不会详细介绍锁的具体实现原理,这会涉及到太多相关知识,笔者不敢误人子弟. 本文要做的就是简单的分析 iOS 开发中常见的几种锁如何实现,以及优缺点是什么,为什么会有性能上

iOS项目开发中的知识点与问题收集整理

注:本文并非绝对原创 大部分内容摘自 http://blog.csdn.net/hengshujiyi/article/details/20943045 文中有些方法可能已过时并不适用于现在的开发环境. 1,Search Bar 怎样去掉背景的颜色(storyboard里只能设置background颜色,可是发现clear Color无法使用). 其实在代码里还是可以设置的,那就是删除背景view  [[self.searchBar.subviews objectAtIndex:0] remov

手把手教你ARC——iOS/Mac开发ARC入门和使用

转载自:http://www.onevcat.com/2012/06/arc-hand-by-hand/ 本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论.请不要将本文的部分或全部内容用于商用,谢谢合作. 欢迎转载本文,但是转载请注明本文出处:http://www.onevcat.com/2012/06/arc-hand-by-hand/ 本文适合人群:对iOS开发有一定基础,熟悉iOS开发中内存管理的Reference Counting机制,对

iOS项目开发中的知识点与问题收集整理(Part 一)

前言部分 注:本文并非绝对原创 大部分内容摘自 http://blog.csdn.net/hengshujiyi/article/details/20943045 文中有些方法可能已过时并不适用于现在的开发环境. 1.Search Bar 怎样去掉背景的颜色(storyboard里只能设置background颜色,可是发现clear Color无法使用). 其实在代码里还是可以设置的,那就是删除背景view  [[self.searchBar.subviews objectAtIndex:0]

ios 界面开发中的常见元素

界面开发中的 CGPoint.CGSize.CGRect.CGRectMake.window(窗口).视图(view)简单记录 定义 /* Points. */ struct CGPoint { CGFloat x; CGFloat y; }; typedef struct CGPoint CGPoint; /* Sizes. */ struct CGSize { CGFloat width; CGFloat height; }; typedef struct CGSize CGSize; /*

Hybrid App Development: 二、关于造轮子以及在Xcode iOS应用开发中加入Cordova

转载请注明出处:http://www.cnblogs.com/xdxer/p/4111552.html [ctrl+左键点击图片可以查看原图] 在上一篇关于Hybrid App Development的文章中,我讨论了一下在iOS下UIWebView的使用方法.但是光使用一个UIWebView所提供的功能还是完全不能满足我们的需求.   关于造轮子的思考: 在UIKit中的UIWebView虽然已经提供了很多功能了,比如JavaScript和Objc之间的通信.但是考虑到一个问题,如果在Hybr