2011-07-29 15 views
27

Następujący kod:dispatch_get_global_queue zachowanie

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"HIGH 1 %d", i); 
    } 
}); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"LOW %d", i); 
    } 
}); 
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    for (int i=0; i<100000; i++) { 
     NSLog(@"HIGH 2 %d", i); 
    } 
}); 

wyniki w mieszaninie wysoko 1 2 wysokiej i niskiej kłody.

Jak to jest, że drukuje jednocześnie logi high1 i high2. nie są blogami high1 i high2 w tej samej kolejce? Czyż nie powinieneś zakończyć high1 bloku przed rozpoczęciem wykonywania bloku high2?

Odpowiedz

22

To zależy od maszyny, na której pracujesz. Podejrzewam, że używasz tego na komputerze Mac, ponieważ GCD automatycznie utworzy wystarczającą liczbę wątków dla określonego systemu dla zadań w globalnych kolejkach. Prawdopodobnie masz więcej niż jeden rdzeń, więc GCD wykonuje twoje zadania na obu rdzeniach.

Jeśli utworzysz kolejkę, używając dispatch_queue_create, otrzymasz kolejkę szeregową, a następnie otrzymasz gwarancję zachowania FIFO.

FWIW (chociaż nie powinieneś polegać na tym zachowaniu), jeśli uruchomisz to na iPhonie, podejrzewam, że zobaczysz zachowanie kolejki szeregowej, ponieważ twój iPhone jest jednordzeniowy. Nie polegaj na tym jednak, iPad 2 jest wielordzeniowy, myślę!

EDIT:

Dokumentacja dispatch_get_global_queue: Zwraca znanej globalnej współbieżne kolejkę danym poziomie priorytetu.

6

Właśnie zilustrowano, dlaczego nie należy wywoływać metod, które nie są bezpieczne dla wątków w wersji dispatch_async. Jeśli istnieje wystarczająco dużo rdzeni przetwarzających, aby wykonać więcej zadań, GCD będzie kontynuował i stos będzie działał na nich niezależnie od tego, czy poprzednie zadania w danej kolejce zostały zwrócone. To samo zachowanie może zostać osiągnięty w OS X 10.7 tworząc własne kolejki z:

dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT); 

Oczywiście NSLog() można nazwać tak często, jak chcesz, nie martwiąc się o uzyskanie dostępu złych błędów lub podobne, ale jeśli jesteś zaniepokojony wątek-bezpieczeństwo lub kolejność, w jakiej powracają twoje zadania, rozważ użycie grup wysyłkowych.

0

dispatch_get_global_queue jest rodzajem kolejki współbieżności. Podając ten sam priorytet dla high1 i high2, wynikiem jest mieszanka high1 i high2. Potem będzie niski wynik, ponieważ ma niższy priorytet.