在多線程訪問可變變量時,是非線程安全的。可能致使程序崩潰。此時,能夠經過使用信號量(semaphore)技術,保證多線程處理某段代碼時,後面線程等待前面線程執行,保證了多線程的安全性。使用方法記兩個就好了,一個是wait(dispatch_semaphore_wait),一個是signal(dispatch_semaphore_signal)。根據dispatch_semaphore_wait的參數類型提示去建立信號量(dispatch_semaphore_t)便可。
感受原理跟PV操做一模一樣。swift
#import <Foundation/Foundation.h> int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); NSMutableArray *lArrM = [NSMutableArray array]; for (int i = 0; i < 100; ++i) { dispatch_async(dispatch_get_global_queue(0, 0), ^{ [lArrM addObject:@(i)]; }); } } return 0; }
運行結果安全
SemephoreTest[3665:130800] Hello, World! SemephoreTest(3665,0x700001daa000) malloc: *** error for object 0x10077b2e0: pointer being freed was not allocated SemephoreTest(3665,0x700001daa000) malloc: *** set a breakpoint in malloc_error_break to debug SemephoreTest(3665,0x700001e2d000) malloc: *** error for object 0x102b00340: pointer being freed was not allocated SemephoreTest(3665,0x700001e2d000) malloc: *** set a breakpoint in malloc_error_break to debug SemephoreTest[3665:130800] lArrM.count:0 (lldb)
// // ViewController.m // SemophoreTest // // Created by LongMa on 2019/8/22. // Copyright © 2019 . All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSMutableArray *lArrM = [NSMutableArray array]; dispatch_semaphore_t lSema = dispatch_semaphore_create(1);//參數1,表明只能有1個線程同時訪問被限制的代碼。 for (int i = 0; i < 1000; ++i) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_semaphore_wait(lSema, DISPATCH_TIME_FOREVER);//wait使信號量的值-1,若是結果爲0,其餘線程來訪問時,須要等待。直到信號量的值大於0 [lArrM addObject:@(i)]; NSLog(@"lArrM.count:%zd",lArrM.count); dispatch_semaphore_signal(lSema);///wait使信號量的值+1,必須和dispatch_semaphore_wait配對使用。 }); } dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"final delayed lArrM.count:%zd",lArrM.count); }); } @end
運行結果(用commandlineTool運行代碼時,log存在不完整問題):多線程
... SemophoreTest[9092:877715] lArrM.count:999 SemophoreTest[9092:877730] lArrM.count:1000 SemophoreTest[9092:877696] final delayed lArrM.count:1000