Jak otázka naznačuje, že spinlocky jsou „odpad“, spinlocky by měly být drženy jen krátce.
Spinlocky nejsou jediným způsobem, jak synchronizovat více vláken. V linuxovém jádře se také používají mutexy/semafory, stejně jako další synchronizační primitiva (např. waitqueues, události).
Nicméně jádro se musí vypořádat s případy, které uživatelský prostor nikdy nevidí, běžným případem jsou manipulátory přerušení. Obslužné rutiny přerušení nelze v Linuxu přeplánovat, ale často musí použít nějaké synchronizační primitivum (např. pro přidání pracovní položky do propojeného seznamu, kterou bude dále zpracovávat nějaké jiné vlákno). Vzhledem k tomu, že obsluhy přerušení nemohou usnout, nemohou používat mutexy, čekací fronty atd. To do značné míry zanechává spinlocky. Pokud vlákno potřebuje synchronizovat přístup s obslužnou rutinou přerušení, musí také používat stejný spinlock.
Spinlocky nejsou nutně odpad. Jsou optimalizovány pro případ non-contention/non-waking a lze je vzít a uvolnit velmi rychle. V takovém případě jsou rychlejší a vyžadují menší režii než jiná synchronizační primitiva.
Volba mezi spinlockem a jinou konstrukcí, která způsobí, že volající zablokuje a vzdá se řízení procesoru, se do značné míry řídí časem, který zabere provedení přepnutí kontextu (uložení registrů/stav v zamykacím vláknu a obnovení registrů/stavu v jiném vlákně). Čas, který to zabere, a také náklady na vyrovnávací paměť mohou být značné.
Pokud se spinlock používá k ochraně přístupu k hardwarovým registrům nebo podobným, kde jakékoli jiné vlákno, které přistupuje, bude trvat jen několik milisekund nebo méně, než uvolní zámek, pak je mnohem lepší využití času procesoru k čekání na roztočení. spíše než přepnout kontext a pokračovat.
Jiní odpověděli. Shrnu případy, kdy byste použili spinlock, a pravidla pro použití spinlocku.
1. Kdy je použit spinlock?
Odpověď:V následujících situacích.
- Vláknu, které drží zámek, není povoleno spát.
- Vlákno, které čeká na uzamčení, nespí, ale točí se v těsné smyčce.
Při správném použití může spinlock poskytnout vyšší výkon než semafor. Příklad:Intrrrupt handler.
2. Jaká jsou pravidla pro používání spinlocků?
Odpověď:
Pravidlo - 1:Jakýkoli kód, který drží spinlock, nemůže z žádného důvodu opustit procesor, kromě přerušení služby (někdy ani potom). Kód držící spinlock tedy nemůže usnout.
Důvod:Předpokládejme, že váš řidič držící spinlock přejde do režimu spánku. Příklad:volá funkci copy_from_user()
nebo copy_to_user()
nebo preempce jádra v procesu s vyšší prioritou odsunula váš kód stranou. Proces účinně uvolní blokaci rotace CPU.
Nyní nevíme, kdy kód uvolní zámek. Pokud by se nějaké jiné vlákno pokusilo získat stejný zámek, točilo by se velmi dlouho. V nejhorším případě by to vedlo k zablokování.
Případ preempce jádra je řešen samotným kódem spinlock. Kdykoli kód jádra obsahuje spinlock, preempce je na příslušném procesoru zakázána. Dokonce i jednoprocesorový systém musí tímto způsobem zakázat preempci.
Pravidlo – 2:Zakažte přerušení na místním CPU, když je blokování spinu pozastaveno.
Důvod:Podpořte svůj ovladač, vezměte spinlock, který řídí přístup k zařízení, a poté vydá přerušení. To způsobí spuštění obsluhy přerušení. Nyní obsluha přerušení také potřebuje zámek pro přístup k zařízení. Pokud obsluha přerušení běží na stejném procesoru, začne se točit. Kód řidiče také nelze spustit k uvolnění zámku. Takže procesor se bude točit navždy.
Pravidlo - 3:Spinlocky musí být drženy po minimální možnou dobu.
Důvod:Dlouhé doby blokování také brání aktuálnímu procesoru v plánování, což znamená, že proces s vyšší prioritou možná bude muset čekat na získání CPU.
Takže to má vliv na latenci jádra (dobu, kterou může proces čekat na naplánování). Typicky by spinlocky měly být drženy po dobu kratší, než kolik potřebuje CPU k přepnutí kontextu mezi vlákny.