標籤:style blog color 使用 os strong
引子:
在取本地連絡人清單的時候看到同事用的這麼一段代碼:
dispatch_semaphore_t sema = dispatch_semaphore_create(0); ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { dispatch_semaphore_signal(sema); }); dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
之前沒有使用過訊號量,但是訊號量這個概念還是有的。
訊號量概述(引用百度百科):
以一個停車場的運作為例。簡單起見,假設停車場只有三個車位,一開始三個車位都是空的。這時如果同時來了五輛車,看 門人允許其中三輛直接進入,然後放下車攔,剩下的車則必須在入口等待,此後來的車也都不得不在入口處等待。這時,有一輛車離開停車場,看門人得知後,開啟 車攔,放入外面的一輛進去,如果又離開兩輛,則又可以放入兩輛,如此往複。在這個停車場系統中,車位是公用資源,每輛車好比一個線程,看門人起的就是訊號量的作用。
抽象的來講,訊號量的特性如下:訊號量是一個非負整數(車位元),所有通過它的線程/進程(車輛)都會將該整數減一(通過它當然是為了使用資源),當該整數值為零時,所有試圖通過它的線程都將處於等待狀態。在訊號量上我們定義兩種操作: Wait(等待) 和 Release(釋放)。當一個線程調用Wait操作時,它要麼得到資源然後將訊號量減一,要麼一直等下去(指放入阻塞隊列),直到訊號量大於等於一時。Release(釋放)實際上是在訊號量上執行加操作,對應於車輛離開停車場,該操作之所以叫做“釋放”是因為釋放了由訊號量守護的資源。
Demo解析
1)
// 建立一個訊號量,值為0 dispatch_semaphore_t sema = dispatch_semaphore_create(0); // 在一個操作結束後發訊號,這會使得訊號量+1 ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) { dispatch_semaphore_signal(sema); }); // 一開始執行到這裡訊號量為0,線程被阻塞,直到上述操作完成使訊號量+1,線程解除阻塞 dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
2)
// 建立一個組 dispatch_group_t group = dispatch_group_create(); // 建立訊號 訊號量為10 dispatch_semaphore_t semaphore = dispatch_semaphore_create(10); // 取得預設的全域並發隊列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); for(inti = 0; i < 100; i++) { // 由於訊號量為10 隊列裡面最多會有10個人任務被執行, dispatch_semaphore_wait(semaphore,DISPATCH_TIME_FOREVER); // 任務加到組內被監聽 dispatch_group_async(group, queue, ^{ NSLog(@"%i",i); sleep(2); dispatch_semaphore_signal(semaphore); }); } // 等待組內所有任務完成,否則阻塞 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); dispatch_release(group); dispatch_release(semaphore);
@mic
(Email:[email protected])
(QQ:839720759)