關于多線程的并發(fā)
菠镇,我們可能會選擇使用NSOperationQueue
來處理,那么在GCD中如何處理多線程的并發(fā)呢?就是dispatch_semaphore
。
在GCD中有三個函數(shù)是semaphore的操作哈踱,分別是:
dispatch_semaphore_create
創(chuàng)建一個semaphore
dispatch_semaphore_signal
發(fā)送一個信號
dispatch_semaphore_wait
等待信號
第一個函數(shù)有一個整形的參數(shù),我們可以理解為信號的總量梨熙,dispatch_semaphore_signal是發(fā)送一個信號开镣,自然會讓信號總量加1,dispatch_semaphore_wait等待信號咽扇,當信號總量少于0的時候就會一直等待邪财,如果線程在一個信號量上等待時,線程會被阻塞
(如果有必要的話)质欲,直至計數(shù)器大于零树埠,然后就可以正常的執(zhí)行,并讓信號總量-1嘶伟,根據(jù)這樣的原理怎憋,我們便可以快速的創(chuàng)建一個并發(fā)控制來同步任務和有限資源訪問控制。
信號量在多線程開發(fā)中被廣泛使用奋早,當一個線程在進入一段關鍵代碼之前盛霎,線程必須獲取一個信號量,一旦該關鍵代碼段完成了耽装,那么該線程必須釋放信號量愤炸。其它想進入該關鍵代碼段的線程必須等待前面的線程釋放信號量。
信號量的具體做法是:當信號計數(shù)大于0時掉奄,每條進來的線程
使計數(shù)減1规个,直到變?yōu)?,變?yōu)?后其他的線程
將進不來姓建,處于等待
狀態(tài)诞仓;執(zhí)行完任務的線程釋放
信號,使計數(shù)加1速兔,如此循環(huán)下去墅拭。
-(void)loginRequest
{
NSLog(@"進入登錄請求");
dispatch_semaphore_t loginSem = dispatch_semaphore_create(0);
NSUserDefaults *userDefault = [NSUserDefaults standardUserDefaults];
NSString *name = [userDefault objectForKey:@"UserName"];
NSString *psw = [userDefault objectForKey:@"Password"];
if (name && psw)
{
//url 登錄請求接口 回調(diào)后做登錄成功與失敗的處理 并釋放信號量
// [self createLoginRequest:name password:psw completion:^(id response, NSString *error) {
// self.loginStatus = error == nil ? true : false;
NSLog(@"登錄返回");
dispatch_semaphore_signal(loginSem);
// }];
} else {
//登錄失敗的處理
//self.loginStatus == false
dispatch_semaphore_signal(loginSem);
}
// 等待重登錄信號
NSLog(@"等待登錄信號");
dispatch_semaphore_wait(loginSem, DISPATCH_TIME_FOREVER);
NSLog(@"通過登錄信號,繼續(xù)執(zhí)行");
// if (self.loginStatus == false)
// {
// if (block) block(nil, @"登錄失敗, 請重新登錄"); // 收到登錄失敗的涣狗,彈個提醒
// return ;
// } else {
// NSLog(@"登錄成功");
// }
}
上面是登錄請求的例子谍婉,請求前創(chuàng)建信號量為0,然后做登錄請求镀钓,當?shù)卿浾埱筇幚硗旰笏氚荆尫判盘柫浚?才會執(zhí)行`通過登錄信號,繼續(xù)執(zhí)行`丁溅。否則沒有釋放信號唤蔗,信號量為0,會一直等待直到其釋放。
參考