{"id":1427,"date":"2018-11-27T17:18:29","date_gmt":"2018-11-27T09:18:29","guid":{"rendered":"http:\/\/www.yusian.com\/blog\/?p=1427"},"modified":"2018-11-27T17:22:56","modified_gmt":"2018-11-27T09:22:56","slug":"%e5%9f%ba%e4%ba%8epthread_mutex%e5%b0%81%e8%a3%85%e7%9a%84%e9%94%81nslock%e3%80%81nscondition%e3%80%81nsconditionlock%e3%80%81nsrecursivelock%e3%80%81synchronized","status":"publish","type":"post","link":"https:\/\/www.yusian.com\/blog\/project\/2018\/11\/27\/1718291427.html","title":{"rendered":"\u57fa\u4e8epthread_mutex\u5c01\u88c5\u7684\u9501NSLock\u3001NSCondition\u3001NSConditionLock\u3001NSRecursiveLock\u3001@Synchronized"},"content":{"rendered":"<p>\u53c2\u8003\u94fe\u63a5\uff1a<a href=\"http:\/\/www.yusian.com\/blog\/project\/2018\/11\/26\/164825.html\" rel=\"noopener\" target=\"_blank\">iOS\u591a\u7ebf\u7a0b\u4e2d\u7684\u51e0\u79cd\u52a0\u9501\u7c7b\u578bOSSpinLock\u3001os_unfair_lock\u3001pthread_mutex<\/a><\/p>\n<p>1\u3001pthread_mutex\u662fc\u8bed\u8a00\u5b9e\u73b0\u7684\u8de8\u5e73\u53f0\u4e92\u65a5\u9501\uff0c\u5e94\u8be5\u662f\u4e00\u79cd\u4e3b\u6d41\u9501\u5427\uff0cOC\u591a\u79cd\u5f62\u6001\u7684\u9501\u90fd\u662f\u57fa\u4e8epthread_mutex\uff0c\u5e38\u89c1\u7684\u6709NSLock\u3001NSCondition\u3001NSConditionLock\u3001NSRecursiveLock\u3001@Synchronized<\/p>\n<p><strong>2\u3001\u5404\u79cd\u9501\u7684\u57fa\u672c\u4f7f\u7528<\/strong><br \/>\n2.1\u3001NSLock<\/p>\n<pre lang=\"objc\" line=\"1\">#import \"ViewController.h\"\r\n#import <pthread.h>\r\n\r\n@interface ViewController ()\r\n{\r\n    NSLock           *_lock;\r\n}\r\n@end\r\n\r\n@implementation ViewController\r\nstatic NSUInteger ticketCount = 20;\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n    _lock = [[NSLock alloc] init];\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        for (int i = 0; i < 5; i++) {\r\n            [self saleTickte];\r\n        }\r\n    });\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        for (int i = 0; i < 5; i++) {\r\n            [self saleTickte];\r\n        }\r\n    });\r\n}\r\n\r\n- (void)saleTickte\r\n{\r\n    [_lock lock];\r\n    \/\/ lockBeforeDate:\u65b9\u6cd5\u80fd\u5728\u6307\u5b9a\u65f6\u95f4\u540e\u81ea\u52a8\u89e3\u9501\r\n    \/\/ [_lock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:3]];\r\n    NSUInteger remain = ticketCount;\r\n    sleep(0.5);\r\n    ticketCount = --remain;\r\n    NSLog(@\"%ld-%@\", ticketCount, [NSThread currentThread]);\r\n    [_lock unlock];\r\n}\r\n@end<\/pre>\n<p>\u8f93\u51fa\u7ed3\u679c\uff1a<!--more--><\/p>\n<pre lang=\"mach\">2018-11-27 16:38:35.510970+0800 MultiThread[5033:2888041] 19-<NSThread: 0x600001ded000>{number = 3, name = (null)}\r\n2018-11-27 16:38:35.511540+0800 MultiThread[5033:2888038] 18-<NSThread: 0x600001de0780>{number = 4, name = (null)}\r\n2018-11-27 16:38:35.512453+0800 MultiThread[5033:2888038] 17-<NSThread: 0x600001de0780>{number = 4, name = (null)}\r\n2018-11-27 16:38:35.513072+0800 MultiThread[5033:2888038] 16-<NSThread: 0x600001de0780>{number = 4, name = (null)}\r\n2018-11-27 16:38:35.513250+0800 MultiThread[5033:2888041] 15-<NSThread: 0x600001ded000>{number = 3, name = (null)}\r\n2018-11-27 16:38:35.513405+0800 MultiThread[5033:2888041] 14-<NSThread: 0x600001ded000>{number = 3, name = (null)}\r\n2018-11-27 16:38:35.513543+0800 MultiThread[5033:2888041] 13-<NSThread: 0x600001ded000>{number = 3, name = (null)}\r\n2018-11-27 16:38:35.513699+0800 MultiThread[5033:2888041] 12-<NSThread: 0x600001ded000>{number = 3, name = (null)}\r\n2018-11-27 16:38:35.513880+0800 MultiThread[5033:2888038] 11-<NSThread: 0x600001de0780>{number = 4, name = (null)}\r\n2018-11-27 16:38:35.514671+0800 MultiThread[5033:2888038] 10-<NSThread: 0x600001de0780>{number = 4, name = (null)}<\/pre>\n<p><strong>PS\uff1a\u4f7f\u7528pthread_mutex\u52a0\u9501\u6f14\u793a\u4e0a\u8ff0\u4ee3\u7801\u7ed3\u679c\u662f\u67d0\u4e2a\u7ebf\u7a0b\u5148\u52a0\u9501\uff0c\u4f3c\u4e4e\u5f53\u524d\u7ebf\u7a0b\u5faa\u73af\u7ed3\u675f\u540e\u624d\u4f1a\u6709\u5176\u4ed6\u7ebf\u7a0b\u6765\u62a2\u5360\uff1b\u4f46NSLock\u7684\u7ed3\u679c\u5373\u662ffor\u5faa\u73af\u968f\u673a\u4ea4\u66ff\u8fdb\u884c\u7684\u3002<\/strong><br \/>\n2.2\u3001NSCondition<\/p>\n<pre lang=\"objc\" line=\"1\">#import \"ViewController.h\"\r\n#import <pthread.h>\r\n\r\n@interface ViewController ()\r\n{\r\n    NSCondition           *_condition;\r\n}\r\n@end\r\n\r\n@implementation ViewController\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n    _condition = [[NSCondition alloc] init];\r\n    \r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodOne];\r\n    });\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodTwo];\r\n    });\r\n}\r\n- (void)methodOne\r\n{\r\n    [_condition lock];\r\n    [_condition wait];\r\n    \/\/ waitUntilDate:\u65b9\u6cd5\u5728\u7b49\u5f85\u65f6\u95f4\u4e4b\u540e\u88ab\u4e3b\u52a8\u5524\u9192\r\n    \/\/ [_condition waitUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];\r\n    NSLog(@\"one, %@\", [NSThread currentThread]);\r\n    [_condition unlock];\r\n}\r\n- (void)methodTwo\r\n{\r\n    \/\/ \u4f11\u77200.5\u79d2\u662f\u4e3a\u4e86\u8ba9\u5176\u4ed6\u7ebf\u7a0b\u5148\u62a2\u5360\u52a0\u9501\r\n    sleep(0.5);\r\n    [_condition lock];\r\n    NSLog(@\"two, %@\", [NSThread currentThread]);\r\n    [_condition signal];\r\n    [_condition unlock];\r\n}\r\n@end<\/pre>\n<p>\u6267\u884c\u7ed3\u679c\uff1a<\/p>\n<pre lang=\"mach\">2018-11-27 16:46:13.041122+0800 MultiThread[5168:2952222] two, <NSThread: 0x60000348a200>{number = 3, name = (null)}\r\n2018-11-27 16:46:13.043408+0800 MultiThread[5168:2952220] one, <NSThread: 0x600003493100>{number = 4, name = (null)}<\/pre>\n<p>2.3\u3001NSConditionLock<\/p>\n<pre lang=\"objc\" line=\"1\">#import \"ViewController.h\"\r\n#import <pthread.h>\r\n\r\n@interface ViewController ()\r\n{\r\n    NSConditionLock           *_conditionLock;\r\n}\r\n@end\r\n\r\n@implementation ViewController\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n    _conditionLock = [[NSConditionLock alloc] initWithCondition:0];\r\n    \r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodOne];\r\n    });\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodTwo];\r\n    });\r\n}\r\n- (void)methodOne\r\n{\r\n    [_conditionLock lockWhenCondition:0];\r\n    \/\/ lock\u65b9\u6cd5\u7b49\u4ef7\u4e8elockWhenCondition:0\r\n    \/\/ [_conditionLock lock];\r\n    \/\/ lockBeforeDate:\u3001lockWhenCondition:beforeDate:\u65b9\u6cd5\u540c\u7406\r\n    \/\/ [_conditionLock lockBeforeDate:[NSDate dateWithTimeIntervalSinceNow:3]];\r\n    \/\/ [_conditionLock lockWhenCondition:0 beforeDate:[NSDate dateWithTimeIntervalSinceNow:3]];\r\n    NSLog(@\"one, %@\", [NSThread currentThread]);\r\n    sleep(1); \r\n    \/\/ \u89e3\u9501\u5f53\u524d\u9501\uff0c\u5e76\u53d1\u9001condition\u4fe1\u53f7\u7ed9\u5176\u4ed6\u6761\u4ef6\u9501\r\n    [_conditionLock unlockWithCondition:1];\r\n}\r\n- (void)methodTwo\r\n{\r\n    \/\/ \u5728\u63a5\u6536\u5230conditon\u4e4b\u524d\u5904\u4e8e\u4f11\u7720\u72b6\u6001\r\n    \/\/ lockWhenCondiont:beforeDate:\u65b9\u6cd5\u53ef\u4ee5\u907f\u514d\u6b7b\u9501\r\n    [_conditionLock lockWhenCondition:1];\r\n    NSLog(@\"two, %@\", [NSThread currentThread]);\r\n    [_conditionLock unlockWithCondition:1];\r\n}\r\n@end<\/pre>\n<p>\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n<pre lang=\"mach\">2018-11-27 16:59:42.482479+0800 MultiThread[5378:3062761] one, <NSThread: 0x60000009a140>{number = 3, name = (null)}\r\n2018-11-27 16:59:43.484827+0800 MultiThread[5378:3062762] two, <NSThread: 0x60000009ac40>{number = 4, name = (null)}<\/pre>\n<p>2.4\u3001NSRecursiveLock<\/p>\n<pre lang=\"objc\" line=\"1\">#import \"ViewController.h\"\r\n#import <pthread.h>\r\n\r\n@interface ViewController ()\r\n{\r\n    NSRecursiveLock           *_recursiveLock;\r\n}\r\n@end\r\n\r\n@implementation ViewController\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n    \/\/ \u7b49\u4ef7\u4e8epthread_mutexattr\u8bbe\u7f6etype PTHREAD_MUTEX_RECURSIVE\r\n    _recursiveLock = [[NSRecursiveLock alloc] init];\r\n    \r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self recursiveMethod];\r\n    });\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self recursiveMethod];\r\n    });\r\n}\r\n- (void)recursiveMethod\r\n{\r\n    static int i = 0;\r\n    [_recursiveLock lock];\r\n    if (i < 5) {\r\n        i++;\r\n        sleep(1);\/\/ \u4f11\u77201\u79d2\u53ef\u4ee5\u770b\u51fa\uff0c\u5f53\u524d\u7ebf\u7a0b\u5360\u7528\u9501\u540e\uff0c\u5176\u4ed6\u7ebf\u7a0b\u65e0\u6cd5\u518d\u6b21\u52a0\u9501\uff0c\u4f46\u5f53\u524d\u7ebf\u7a0b\u53ef\u4ee5\r\n        NSLog(@\"%d, %@\", i, [NSThread currentThread]);\r\n        [self recursiveMethod];\r\n    }\r\n    [_recursiveLock unlock];\r\n    i = 0;\r\n}\r\n@end<\/pre>\n<p>\u8fd0\u884c\u7ed3\u679c\uff1a<\/p>\n<pre lang=\"mach\">2018-11-27 17:08:30.437419+0800 MultiThread[5575:3146772] 1, <NSThread: 0x60000246f940>{number = 3, name = (null)}\r\n2018-11-27 17:08:31.441390+0800 MultiThread[5575:3146772] 2, <NSThread: 0x60000246f940>{number = 3, name = (null)}\r\n2018-11-27 17:08:32.444975+0800 MultiThread[5575:3146772] 3, <NSThread: 0x60000246f940>{number = 3, name = (null)}\r\n2018-11-27 17:08:33.448204+0800 MultiThread[5575:3146772] 4, <NSThread: 0x60000246f940>{number = 3, name = (null)}\r\n2018-11-27 17:08:34.451139+0800 MultiThread[5575:3146772] 5, <NSThread: 0x60000246f940>{number = 3, name = (null)}\r\n2018-11-27 17:08:35.454776+0800 MultiThread[5575:3146773] 1, <NSThread: 0x600002474000>{number = 4, name = (null)}\r\n2018-11-27 17:08:36.459969+0800 MultiThread[5575:3146773] 2, <NSThread: 0x600002474000>{number = 4, name = (null)}\r\n2018-11-27 17:08:37.462625+0800 MultiThread[5575:3146773] 3, <NSThread: 0x600002474000>{number = 4, name = (null)}\r\n2018-11-27 17:08:38.466880+0800 MultiThread[5575:3146773] 4, <NSThread: 0x600002474000>{number = 4, name = (null)}\r\n2018-11-27 17:08:39.472285+0800 MultiThread[5575:3146773] 5, <NSThread: 0x600002474000>{number = 4, name = (null)}<\/pre>\n<p>2.5\u3001@synchronized(token){}<\/p>\n<pre lang=\"objc\" line=\"1\">#import \"ViewController.h\"\r\n#import <pthread.h>\r\n\r\n@implementation ViewController\r\n- (void)viewDidLoad\r\n{\r\n    [super viewDidLoad];\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodOne];\r\n    });\r\n    dispatch_async(dispatch_get_global_queue(0, 0), ^{\r\n        [self methodTwo];\r\n    });\r\n}\r\n- (void)methodOne\r\n{\r\n    \/\/ token\u76f8\u540c\u5373\u4e3a\u540c\u4e00\u9501\uff0c\u5927\u62ec\u53f7\u5f00\u59cb\u4e3a\u52a0\u9501\uff0c\u7ed3\u679c\u4e3a\u89e3\u9501\uff0c\u4f7f\u7528\u7b80\u5355\u4f46\u6548\u7387\u4e0d\u9ad8\r\n    @synchronized (self) {\r\n        NSLog(@\"one, %@\", [NSThread currentThread]);\r\n        sleep(1);\r\n    }\r\n}\r\n- (void)methodTwo\r\n{\r\n    @synchronized (self) {\r\n        NSLog(@\"two, %@\", [NSThread currentThread]);\r\n    }\r\n}\r\n@end<\/pre>\n<p>\u6267\u884c\u7ed3\u679c\uff1a<\/p>\n<pre lang=\"mach\">2018-11-27 17:15:02.233273+0800 MultiThread[5688:3202460] one, <NSThread: 0x60000312d780>{number = 3, name = (null)}\r\n2018-11-27 17:15:03.237778+0800 MultiThread[5688:3202462] two, <NSThread: 0x60000312ec80>{number = 4, name = (null)}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u53c2\u8003\u94fe\u63a5\uff1aiOS\u591a\u7ebf\u7a0b\u4e2d\u7684\u51e0\u79cd\u52a0\u9501\u7c7b\u578bOSSpinLock\u3001os_unfair_lock\u3001pthread_mutex 1\u3001pthread_mutex\u662fc\u8bed\u8a00\u5b9e\u73b0\u7684\u8de8\u5e73\u53f0\u4e92\u65a5\u9501\uff0c\u5e94\u8be5\u662f\u4e00\u79cd\u4e3b\u6d41\u9501\u5427\uff0cOC\u591a\u79cd\u5f62\u6001\u7684\u9501\u90fd\u662f\u57fa\u4e8epthread_mutex\uff0c\u5e38\u89c1\u7684\u6709NSLock\u3001NSCondition\u3001NSConditionLock\u3001NSRecursiveLock\u3001@Synchronized 2\u3001\u5404\u79cd\u9501\u7684\u57fa\u672c\u4f7f\u7528 2.1\u3001NSLock #import &#8220;ViewController.h&#8221; #import @interface ViewController () { NSLock *_lock; } @end @implementation ViewController static NSUInteger ticketCount = 20; &#8211; (void)viewDidLoad { [super viewDidLoad]; _lock = [[NSLock alloc] init]; dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i = 0; i < 5; i++) { [self saleTickte]; } }); dispatch_async(dispatch_get_global_queue(0, 0), ^{ for (int i [&hellip;]\n<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[194,195,192,180,193],"class_list":["post-1427","post","type-post","status-publish","format-standard","hentry","category-project","tag-pthread_mutex","tag-195","tag-192","tag-180","tag-193"],"_links":{"self":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1427","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/comments?post=1427"}],"version-history":[{"count":0,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/posts\/1427\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/media?parent=1427"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/categories?post=1427"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yusian.com\/blog\/wp-json\/wp\/v2\/tags?post=1427"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}