2010-02-24 11 views
9

select() jest świetnym wywołaniem systemowym. Możesz spakować dowolną liczbę deskryptorów plików, deskryptorów gniazd, potoków itp., A otrzymasz powiadomienie w synchroniczny sposób, gdy dane wejściowe staną się dostępne.select() - w stanie timerów

Czy istnieje sposób na utworzenie timera interwałowego/onehotowego i użycie go z select()? To zaoszczędziłoby mi wiele wątków na IO i czas.

+1

Czy możesz wyjaśnić, jaki rodzaj zegara chcesz? 'select()' ma standardowy parametr timeout. – qrdl

+0

Parametr timera jest używany wewnętrznie przez select(). Jeśli select() nie otrzyma żadnego oczekującego odczytu/zapisu/err przed tym przekroczeniem czasu, to powróci. To, czego szukam, to polecenie przekształcenia licznika czasu w plik danych i spakowania go w zestawie fd_set. –

+0

Parametr limitu czasu wybierania jest przeznaczony tylko dla limitów czasu, jeśli nie ma innych zdarzeń, jest całkiem sporo pracy, aby zbudować kilka timerów interwałowych i timerów oneshot na tym – nos

Odpowiedz

12

timerfd_create robi dokładnie to. Jest to całkiem nowy dodatek do jądra Linuksa i może nie być jeszcze dostępny we wszystkich dystrybucjach.

+0

Wow .. Jak o tym nie wiedziałem? Muszę odświeżyć system linuxowy. –

+2

To też jest sygnał wywoławczy, na wypadek, gdybyś chciał otrzymywać sygnały również jako zdarzenia fd :-) – nos

7

Użyj parametru limitu czasu - zatrzymaj zdarzenia licznika w kolejce priorytetowej, sprawdź najwyższy element i ustaw odpowiednio limit czasu - jeśli limit czasu zostanie osiągnięty, możesz sprawdzić, czy zdarzenie jest gotowe do uruchomienia, uruchomić wydarzenie i dalej.

Przynajmniej to robię.

Należy pamiętać, że ankieta ma ładniejszy interfejs (w pewnym sensie) i może być bardziej wydajna z wieloma deskryptorami plików.

+0

+1 To jest przenośne rozwiązanie. –

+0

+1 dzięki Mark. Czy masz jakiś wskaźnik do kodu przykładowego lub FOSS, korzystając z podpowiedzi, którą zasugerowałeś? – Viet

2

MarkR ma ładny przenośne rozwiązanie, ale tutaj jest inny:

Użyj czasomierza POSIX (timer_create) można przekształcić problem w „select sygnałów -able”. Ten problem ma klasyczne rozwiązanie: zapisywanie do potoku z modułu obsługi sygnału i odczytywanie na końcu odczytu potoku.

+1

Wow, to było dokładnie to, czego szukałem. Dzięki! :) – troglobit

0

Opierając się na @MarkR, używając posortowanej struktury do przechowywania wywołania zwrotnego + zamknięcia z int i wskaźnikiem do int. Jeśli dwa int mają tę samą wartość, to zdarzenie jest aktywne, w przeciwnym razie zostało odrzucone.

W ten sposób zdarzenia można odrzucić, po prostu zwiększając liczbę int. Być może nie jest to najprostsze rozwiązanie, ale było to wszystko, co mogłem wymyślić.

https://github.com/cheako/tor2web/tree/6ac67f80daaea01d14a5d07e6026e1af4258dc96/src

hextree.c contains the code for the data structure used. 
schedule.c:156 is where the int is changed. 
gnutls.c:197 is where the timers are created.