2012-09-07 66 views
1

我很好奇使用dispatch_afterdispatch_semaphore_t一起執行一些任務,並在每個線程之間等待一段時間。如何讓dispatch_after和dispatch_semaphore_t在GCD中一起工作?

我使用下面的代碼:

dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull * NSEC_PER_SEC); 

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); 

dispatch_after(time, queue, ^{ 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    NSLog(@"blk01"); 

    dispatch_semaphore_signal(semaphore); 

}); 

dispatch_after(time, queue, ^{ 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    NSLog(@"blk02"); 

    dispatch_semaphore_signal(semaphore); 

}); 

dispatch_after(time, queue, ^{ 

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    NSLog(@"blk03"); 

    dispatch_semaphore_signal(semaphore); 

}); 

我得到線程的執行在3秒後,不與預期延遲。

我在做什麼錯?是否有任何其他方式來執行dispatch_semaphore_t中的線程,每個線程執行之間有延遲時間?

回答

4

如果您想連續執行三個塊(不是同時執行),並且您希望在塊之間暫停,則使用比使用信號量更簡單的方法。最簡單的是隻創建一個串行隊列,並在每個塊的開頭或結尾放sleep(或usleep):

dispatch_queue_t queue = dispatch_queue_create("my queue", 0); 

dispatch_async(queue, ^{ 
    sleep(3); 
    NSLog(@"blk01"); 
}); 

dispatch_async(queue, ^{ 
    sleep(3); 
    NSLog(@"blk02"); 
}); 

dispatch_async(queue, ^{ 
    sleep(3); 
    NSLog(@"blk03"); 
}); 

dispatch_release(queue); 

sleep在你的街區是很簡單的,但聯繫了一個線程。這可能並不重要,除非你創造了許多隊列並在其中許多隊列中休眠。

如果你告訴我們爲什麼你認爲你需要一個信號量,或許我們可以爲你提供一個更好的選擇或建議如何正確使用它。

+0

它就像一個魅力,沒有什麼特別與dispatch_semaphore_t只是好奇,並有正確的方式來做到這一點。 – chroman

+0

如果塊執行超過setuped時間,該怎麼辦? –

3

您的代碼不會要求每次調用之間的延遲時間爲3秒。它在同一時間調度3個塊,所有3個塊都用信號量和日誌。

您可能需要調整每個後續塊的調度時間,或者需要安排每個先前調用中的後續dispatch_after()調用。前者可能更簡單,並會讓你更精確的時機。如果你選擇後者,一定要在每個塊中重新計算time,因爲這是指絕對時間,而不是相對持續時間。

+0

是的,幾次嘗試只是調整時間。非常感謝您對絕對/相對時間的解釋。 – chroman

相關問題