Oto bezpośredni cytat z Essential Linux Device Drivers, który może być tym, czego szukasz. Wydaje części dotyczącej pilocie na końcu może być to, co cię interesuje.
Czytnik Zamki
Kolejny specjalistyczny mechanizm regulacji współbieżności jest wariantem Czytnik z spinlocks. Jeśli użycie sekcji krytycznej jest takie, że oddzielne wątki odczytują lub zapisują do współużytkowanej struktury danych, ale nie robią tego, oba te blokady są naturalnym dopasowaniem. Wiele wątków czytnika może jednocześnie znajdować się w krytycznym obszarze. Czytnik spinlocks są zdefiniowane w następujący sposób:
rwlock_t myrwlock = RW_LOCK_UNLOCKED;
read_lock(&myrwlock); /* Acquire reader lock */
/* ... Critical Region ... */
read_unlock(&myrwlock); /* Release lock */
Jeżeli jednak nić autor wprowadza krytyczny punkt inne czytniki lub wystawca wątki nie mogą w środku. Aby korzystać pisarz spinlocks, należy napisać to:
rwlock_t myrwlock = RW_LOCK_UNLOCKED;
write_lock(&myrwlock); /* Acquire writer lock */
/* ... Critical Region ... */
write_unlock(&myrwlock); /* Release lock */
Spójrz na kod routingu IPX Obecnie w net/ipx/ipx_route.c
dla prawdziwego życia przykładzie spinlock Czytnik. Blokada czytnika-czytnika o nazwie ipx_routes_lock
chroni tabelę routingu IPX przed równoczesnym dostępem.Wątki , które muszą wyszukać tabelę routingu, aby przesłać pakiety blokad czytnika. Wątki, które trzeba dodać, lub usunąć wpisy z tabeli routingu, przechwytują blokady pisarzy. Poprawia to wydajność, ponieważ zazwyczaj jest znacznie więcej instancji routingowych wyszukiwań tabel niż aktualizacji tabel routingu.
jak zwykłe spinlocks, zamki Czytnik posiada również odpowiadający IRQ warianty mianowicie, read_lock_irqsave()
, read_lock_irqrestore()
, write_lock_irqsave()
i write_lock_irqrestore()
. Semantyka tych funkcji jest podobna do funkcji zwykłych spinlocków.
Blokady sekwencji lub seqlocks, wprowadzone w jądrze 2.6, są blokadami czytnika-pisarza, gdzie pisarze są uprzywilejowani nad czytnikami . Jest to użyteczne, jeśli operacje zapisu na zmiennej znacznie większej liczbie odczytów mają dostęp. Przykładem jest zmienna jiffies_64
omówiona wcześniej w tym rozdziale. Wpisy wątku nie czekają na czytelników, którzy mogą znajdować się w sekcji krytycznej. Z tego powodu, nici czytelnik może dowiedzieć się, że ich pozycja wewnątrz sekcji krytycznej uchybiła i może trzeba powtórzyć:
u64 get_jiffies_64(void) /* Defined in kernel/time.c */
{
unsigned long seq;
u64 ret;
do {
seq = read_seqbegin(&xtime_lock);
ret = jiffies_64;
} while (read_seqretry(&xtime_lock, seq));
return ret;
}
Pisarze ochrony obszarów krytycznych za pomocą write_seqlock()
i write_sequnlock()
.
jądra 2.6 wprowadzono inny mechanizm zwany Read-Copy Update (RCU), co daje wydajność poprawiła gdy czytelnicy daleko przewyższają liczebnie pisarzy. Podstawową ideą jest to, że wątki czytników można wykonywać bez blokowania . Nitki pisarskie są bardziej złożone. Wykonują operacje aktualizacji na kopii struktury danych i zastępują wskaźnik wyświetlany przez czytniki. Oryginalna kopia jest zachowywana aż do następnego przełączenia kontekstu wszystkich procesorów na , aby zapewnić zakończenie wszystkich operacji odczytu. Należy pamiętać, że używanie RCU jest bardziej zaangażowane niż dotychczasowe prymitywy i powinno być używane tylko wtedy, gdy masz pewność, że jest to właściwe narzędzie do pracy. Dane RCU: Struktury i funkcje interfejsu są zdefiniowane w include/linux/rcupdate.h
. Istnieje obszerna dokumentacja w Documentation/RCU/*
.
Dla przykładu użycia RCU, spójrz na fs/dcache.c
. W systemie Linux każdy plik jest powiązany z informacjami o katalogu (przechowywanymi w strukturze zwanej zębem zębatym), informacjami o metadanych (przechowywanymi w i-węle) i rzeczywistymi danymi (przechowywanymi w blokach danych). Za każdym razem, gdy operujesz na pliku, komponenty ścieżki pliku są analizowane, a odpowiadające im diceri uzyskują. Dicer przechowywane są w pamięci podręcznej w strukturze danych zwanej dcache, aby przyspieszyć przyszłe operacje. W dowolnym momencie liczba wyszukiwań dcache jest znacznie większa niż aktualizacje dcache, więc odniesienia do dcache są chronione przy pomocy prymitywów RCU.
Nie znam odpowiedzi na to pytanie, ale książka "Understanding the Linux Kernel" ma wiele dobrych informacji na temat tego typu rzeczy. To naprawdę świetna książka, każdy, kto zajmuje się jądrem, powinien ją przeczytać. – Zifre
Nie wiem zbyt wiele o wewnętrznych elementach współbieżnych jądra, ale można je przetworzyć za pomocą licznika czytnik/program piszący i blokować pisownię. –
@Nir Cieszę się, że w końcu przyjąłeś odpowiedź po 4 latach :-) –