2010-10-21 5 views
13

Pisałem jakiś kod, który zastępuje niektóre istniejące:Jaka jest różnica między źródłami wysyłania GCD i select()?

while(runEventLoop){ 
    if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){ 
    // check file descriptors for activity and dispatch events based on same 
    } 
} 

gniazdo odczyt kodów. Chciałbym to zmienić, aby użyć kolejki GCD, tak aby móc umieszczać zdarzenia w kolejce przy użyciu metody dispatch_async, zamiast utrzymywać tablicę "musi być wywołana przy następnej iteracji". Używam również kolejki GCD do/zawierającej/tę konkretną akcję, dlatego chcę przekazać ją bardziej naturalnej formie wysyłkowej GCD. (Nie pętli while() monopolizacyjnego kolejkę szeregowej)

Jednak, kiedy próbuje byłaby to w formie oparła się na źródłach wysyłkowych zwolniony z obsługi zdarzeń związanych z DISPATCH_SOURCE_TYPE_READ i DISPATCH_SOURCE_TYPE_WRITE na deskryptorach portami kodu biblioteki, które w zależności od tego harmonogramu przestał działać. Moje pierwsze założenie jest takie, że nieporozumienie przy korzystaniu z DISPATCH_SOURCE_TYPE_READ i DISPATCH_SOURCE_TYPE_WRITE - założyłem, że przyniosą one mniej więcej takie samo zachowanie, jak wywoływanie select() z tymi deskryptorami gniazd.

Czy źle rozumiem źródła wysyłki GCD? Lub, jeśli chodzi o refaktor, czy używam go w sytuacji, w której nie jest najlepiej dopasowany?

+0

Powinieneś pokazać swój kod - co wypróbowałeś. W międzyczasie Mike Ash ma pewien przykładowy kod do sprawdzenia - http://www.mikeash.com/svn/GCDWeb/GCDWeb.m - serwer WWW GCD. – robertvojta

Odpowiedz

3

Krótka odpowiedź na Twoje pytanie brzmi: brak. Nie ma żadnych różnic, zarówno źródła wysyłania GCD, jak i select() robią to samo: powiadamiają użytkownika o tym, że zdarzyło się konkretne zdarzenie jądra lub że określony warunek jest prawdziwy.

zauważyć, że na komputerze Mac lub urządzeniu z iOS nie należy używać select(), ale raczej bardziej zaawansowane kqueue() i kevent() (lub kevent64()).

Możesz z pewnością przekonwertować kod na źródła wysyłki GCD, ale musisz zachować ostrożność, aby nie złamać innego kodu, który polega na tym. Wymaga to pełnej kontroli wszystkich sygnałów obsługi kodu, deskryptorów plików, gniazd i wszystkich innych zdarzeń jądra niskiego poziomu.

Może być prostszym rozwiązaniem może być zachowanie oryginalnego kodu, po prostu dodanie kodu GCD w części, która reaguje na zdarzenia. Tutaj możesz wysyłać zdarzenia w różnych kolejkach w zależności od określonego rodzaju zdarzenia.

+0

Zgadzam się, jedną z różnic jest to, że z GCD można modularyzować swój kod na oddzielne maszyny stanów z niezależnymi kolejkami wysyłkowymi związanymi z każdym źródłem. Nie jestem pewien, ale myślę, że wewnętrznie GCD może używać czegoś podobnego do wyboru samego siebie. – user210504

+2

Czy możesz dokładniej określić, dlaczego funkcja kqueue() jest lepsza niż select() w systemie iOS? Z moich krótkich eksploracji wygląda na to, że kqueue() jest preferowany, gdy masz wiele zdarzeń do monitorowania, ale czy istnieje jakikolwiek powód, aby sądzić, że jest lepszy niż select() na fdset z pojedynczym fd? W takim przypadku wydaje się, że semantyka jest prawie identyczna, więc nie jesteśmy pewni, dlaczego wydajność byłaby inna? – user1055568

+1

Występy są naprawdę różne: po prostu spróbuj sam. Powinieneś to zobaczyć, nawet dla pojedynczego deskryptora pliku z intensywną aktywnością, kqueue() działa lepiej. Prawdopodobnie Apple nie nalegał na zbytnią poprawę starej implementacji select(). Nowe wywołanie systemowe queue() jest znacznie wydajniejsze i działa lepiej. Jedynym powodem, dla którego widzę użycie select(), jest to, że masz starszego kodu, którego nie chcesz aktualizować. –