信號量Semaphore
信號量是多線程編程中一項很重要的技術。在GCD中告组,使用dispatch_semaphore來表示信號量,相關函數有3個:
1、dispatch_semaphore_create(value) ? 創(chuàng)建信號量,參數表示信號量的數值(可以簡單的理解為同時能有幾個線程執(zhí)行操作)
2价捧、dispatch_semaphore_wait(semaphore,time) ?等待信息量饭耳,即把信號量數值減一。第一個參數為信號量對象遗增,第二個為等待超時的時間
3、dispatch_semaphore_singal(semaphore) 發(fā)送一個信號款青,即信息量數值加一做修。參數為信號量對象
信號量技術,通常用來:
1抡草、使異步操作變?yōu)橥讲僮?/p>
2饰及、加鎖操作,保證線程安全
話不多說康震,上代碼燎含。
? ? dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
? ? dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
? ? dispatch_block_t task1 = dispatch_block_create(0, ^{
? ? ? ? NSLog(@" task1 begin");
? ? ? ? [NSThread sleepForTimeInterval:5];
? ? ? ? NSLog(@"task1 end");
? ? });
? ? dispatch_block_t task2 = dispatch_block_create(0, ^{
? ? ? ? ? NSLog(@" task2 begin");
? ? ? ? ? [NSThread sleepForTimeInterval:1.5];
? ? ? ? ? NSLog(@"task2 end");
? ? });
? ? dispatch_block_t task3 = dispatch_block_create(0, ^{
? ? ? ? ? NSLog(@" task3 begin");
? ? ? ? ? [NSThread sleepForTimeInterval:3];
? ? ? ? ? NSLog(@"task3 end");
? ? });
? ? dispatch_async(concurrentQueue, ^{
? ? ? ? task1();
? ? });
? ? dispatch_async(concurrentQueue, ^{
? ? ? ? dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
? ? ? ? task2();
? ? ? ? dispatch_semaphore_signal(semaphore);
? ? });
? ? dispatch_async(concurrentQueue, ^{
? ? ? ? dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
? ? ? ? task3();
? ? ? ? dispatch_semaphore_signal(semaphore);
? ? });
? ? dispatch_block_notify(task1, dispatch_get_main_queue(), ^{
? ? ? ? dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
? ? ? ? NSLog(@"this is main thread,refreshUI");
? ? ? ? dispatch_semaphore_signal(semaphore);
? ? });
以上代碼,使用信號量腿短,結合dispatch_block_notify屏箍,實現了task3在task2執(zhí)行結束后再執(zhí)行,task4(刷新UI的操作)在所有任務執(zhí)行結束后再執(zhí)行橘忱。當然也可以使用dispatch_group實現相同的業(yè)務場景赴魁,其實dispatch_group底層就是用dispathch_semaphore來實現的。
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1);
? ? dispatch_queue_t queue1 = dispatch_queue_create("queue1", DISPATCH_QUEUE_SERIAL);
? ? dispatch_queue_t queue2 = dispatch_queue_create("queue2", DISPATCH_QUEUE_SERIAL);
? ? dispatch_block_t task = ^{
? ? ? ? while(true) {
? ? ? ? ? ? dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER);
? ? ? ? ? ? if(self.theCount>0) {
? ? ? ? ? ? ? ? self.theCount--;
? ? ? ? ? ? ? ? NSLog(@"%@吃掉了一個蘋果,剩余%d個蘋果",[NSThread currentThread],self.theCount);
? ? ? ? ? ? ? ? [NSThread sleepForTimeInterval:0.2];
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? NSLog(@"沒有蘋果了");
? ? ? ? ? ? ? ? dispatch_semaphore_signal(semaphore);
? ? ? ? ? ? ? ? break;//沒有時跳出循環(huán)
? ? ? ? ? ? }
? ? ? ? ? ? dispatch_semaphore_signal(semaphore);
? ? ? ? }
? ? };
? ? dispatch_async(queue1, task);
? ? dispatch_async(queue2, task);
以上代碼钝诚,使用信號量颖御,實現了鎖操作,保證線程安全凝颇。