NSLock 解读

上一篇大概介绍了一下锁的分类

这篇我们就解读一下第一个锁 NSLock

NSLock是Foundation提供的类,NSLock的API很少也很简单。常用的就几个方法

备注:深入解读 NSLock则需要 Foundation 源码, 但是这里公开的Foundation框架中只有NSObject的实现。假如我们想要查看NSString,NSArray,NSRunLoop,NSThread等Foundation这些类,是没有源码的。虽然通过汇编语言,一步步的跟踪也可以查看。但是汇编太过于晦涩难懂,所以这里推荐一个GNUstep

GNUstep是GUN计划的项目之一,它将Cocoa的OC库重新开源实现了一遍,并且开源出来了。虽然GNUstep不是苹果官方的源码,是GNU计划写的,但是还是具有一定参考价值的。

GNUstep源码下载地址:http://www.gnustep.org/resources/downloads.php

一. NSLock 互斥锁 不能多次调用 lock方法,会造成死锁 ,遵循 NSLocking 协议。进行加锁、解锁

@protocol NSLocking

(void)lock;//加锁

(void)unlock;//解锁

@end

NSLock实现了NSLocking协议:

@interface NSLock : NSObject {

@private

void *_priv;

}

// 尝试获取锁,获取到返回YES,获取不到返回NO

(BOOL)tryLock;

// 在指定时间点之前获取锁,能够获取返回YES,获取不到返回NO

(BOOL)lockBeforeDate:(NSDate *)limit;

// 锁名称,如果使用锁出现异常,输出的log中会有

@property (nullable, copy) NSString *name API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));

@end

-tryLock:如果能获取到锁返回YES,如果获取不到锁返回NO,但不会使线程进入休眠,会继续向下执行

-lockBeforeDate::如果锁已被锁定,在指定的时间点之前线程进入休眠等待锁释放。如果在时间点之前锁被释放了,线程立即被唤醒获得锁,该函数会返回YES,继续执行任务,不会一直休眠等到那个时间点。如果等到时间点还没有获得锁会返回NO,并继续执行任务

NSLock是非递归锁,不能重入,否则会发生死锁:

上代码~~~

可以看到上面的代码最终只打印了testLock1,其他的几个打印不会去执行。因为 testLock1被锁了之后,还没有调用解锁就执行了testLock2。这个时候去lock 但是锁获取不到就休眠等待,直到testLock1 unlock解锁之后才会继续执行,但是这个时候testLock2 不执行完, testLock1 里面的代码也就被卡着不能继续。

注意:

-lock和-unlock必须在相同的线程调用,也就是说,他们必须在同一个线程中成对调用,否则会产生未知结果。

官方文档原文:Unlocking a lock from a different thread can result in undefined behavior.

可以阅读 GNUstep 的 Foundation (参考),也可以自行下载 swift 版本的 Foundation 源码分析


通过源码可知验证 NSLock 是对 pthread 中互斥锁 的封装。

其他都好理解,这里列一下 timedLock() 的实现流程:

1、设定超时时间,进入while循环。

2、pthread_cond_timedwait()在本次循环中计时等待,线程进入休眠

3、等待超时,直接返回 false;

4、如果等待没有超时,期间锁被释放,线程会被唤醒,再次尝试获取锁 pthread_mutex_trylock(),如果获取成功返回true

5、即没有超时,被唤醒后也没有成功获取到锁(被其他线程抢先获得锁),重新计算超时时间进入下一次while循环

NSLock 坑(网上看的例子,解读一下)

代码先执行第 38 行,然后执行第 31 行,此时锁被 lock,然后继续执行 if 里面,因为里面有 testMethod(value-1),所以又开始调用[lock lock]方法,此时的锁一直处于 lock 状态,if 还没执行完,没有 unlock,所以NSlog 只会打印一次

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,302评论 5 470
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,232评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,337评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,977评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,920评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,194评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,638评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,319评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,455评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,379评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,426评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,106评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,696评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,786评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,996评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,467评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,043评论 2 341

推荐阅读更多精彩内容

  • 1、TCP连接的三次握手过程? 第一次握手:客户端发送 syn 包(syn=j)到服务器,并进入 SYN_SEND...
    异乡人_4f2a阅读 654评论 0 2
  • 什么会给多线程的安全造成隐患? 有了多线程技术支持,我们可以并发的进行多个任务,因此同一块资源就有可能在多个线程中...
    RUNNING_NIUER阅读 3,306评论 6 32
  • 对于从多个执行线程安全访问资源,应用程序中多个线程的存在会导致潜在的问题。修改相同资源的两个线程可能会以出乎意料的...
    渐z阅读 379评论 0 0
  • 1、iOS代码规范 https://developer.apple.com/library/archive/rel...
    張小明阅读 1,090评论 0 0
  • 一 iOS多线程介绍 二 线程同步方案 一 iOS多线程介绍 首先我们先了解一下关于线程的几个概念: 1 什么是进...
    当前明月阅读 541评论 0 2