1.信號(hào)量使用
信號(hào)量:就是一種可用來(lái)控制訪問(wèn)資源的數(shù)量的標(biāo)識(shí),設(shè)定了一個(gè)信號(hào)量,在線程訪問(wèn)之前篱蝇,加上信號(hào)量的處理,則可告知系統(tǒng)按照我們指定的信號(hào)量數(shù)量來(lái)執(zhí)行多個(gè)線程徽曲。
在GCD中有三個(gè)函數(shù)是semaphore的操作,
分別是:
//創(chuàng)建信號(hào)量麸塞,參數(shù):信號(hào)量的初值秃臣,如果小于0則會(huì)返回NULL
dispatch_semaphore_create(信號(hào)量值)
//等待降低信號(hào)量
dispatch_semaphore_wait(信號(hào)量,等待時(shí)間)
//提高信號(hào)量
dispatch_semaphore_signal(信號(hào)量)
注意哪工,正常的使用順序是先降低然后再提高奥此,這兩個(gè)函數(shù)通常成對(duì)使用
問(wèn)題描述
假設(shè)現(xiàn)在系統(tǒng)有兩個(gè)空閑資源可以被利用,但同一時(shí)間卻有三個(gè)線程要進(jìn)行訪問(wèn)雁比,這種情況下稚虎,該如何處理呢?
代碼如下:
- (void)dispatchSignal {
//crate的value表示偎捎,最多幾個(gè)資源可訪問(wèn)
dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
//任務(wù)1
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 1");
sleep(1);
NSLog(@"complete task 1");
dispatch_semaphore_signal(semaphore);
});
//任務(wù)2
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 2");
sleep(1);
NSLog(@"complete task 2");
dispatch_semaphore_signal(semaphore);
});
//任務(wù)3
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"run task 3");
sleep(1);
NSLog(@"complete task 3");
dispatch_semaphore_signal(semaphore);
});
}
執(zhí)行結(jié)果如下:總結(jié):由于設(shè)定的信號(hào)值為2蠢终,先執(zhí)行兩個(gè)線程,等執(zhí)行完一個(gè)茴她,才會(huì)繼續(xù)執(zhí)行下一個(gè)寻拂,保證同一時(shí)間執(zhí)行的線程數(shù)不超過(guò)2。
注意:保證同一時(shí)間執(zhí)行的線程數(shù)不超過(guò)2丈牢,但并不會(huì)保證必須在前兩個(gè)執(zhí)行結(jié)束才會(huì)執(zhí)行第三個(gè)祭钉,可能會(huì)有第二個(gè)執(zhí)行時(shí)間較長(zhǎng),第一條線程執(zhí)行完之后己沛,就會(huì)去執(zhí)行第3個(gè)任務(wù)慌核,
如果把信號(hào)量設(shè)置為1距境,則按順序執(zhí)行,任務(wù)1-任務(wù)2-任務(wù)3垮卓,想要完全保證第3個(gè)任務(wù)垫桂,在前兩個(gè)之后,可以使用dispatch_group
假設(shè)我們?cè)O(shè)定信號(hào)值=1
dispatch_semaphore_create(1)
結(jié)果如下:設(shè)置為1代表三個(gè)任務(wù)按順序執(zhí)行
設(shè)定信號(hào)值=3