GNU/Linux >> Znalost Linux >  >> Linux

Stavy procesu Linuxu

Při čekání na read() nebo write() do/z návratu deskriptoru souboru bude proces uveden do zvláštního druhu spánku, známého jako "D" nebo "Disk Sleep". To je zvláštní, protože proces nelze v takovém stavu zabít ani přerušit. Proces čekající na návrat z ioctl() by se tímto způsobem také uspal.

Výjimkou je, když je soubor (například terminál nebo jiné znakové zařízení) otevřen v O_NONBLOCK režim, prošel, když se předpokládá, že zařízení (jako je modem) bude potřebovat čas na inicializaci. Ve své otázce jste však uvedli bloková zařízení. Také jsem nikdy nezkoušel ioctl() který se pravděpodobně zablokuje na fd otevřeném v neblokujícím režimu (alespoň ne vědomě).

To, jak se zvolí jiný proces, zcela závisí na plánovači, který používáte, a také na tom, co jiné procesy mohly udělat, aby upravily své váhy v tomto plánovači.

Je známo, že některé programy v uživatelském prostoru za určitých okolností zůstávají v tomto stavu navždy, dokud nebudou restartovány. Tito jsou obvykle seskupeni s jinými "zombiemi", ale tento termín by nebyl správný, protože nejsou technicky zaniklé.


Proces provádějící I/O bude uveden do stavu D (nepřerušitelný spánek) , který uvolní CPU, dokud nenastane hardwarové přerušení, které CPU řekne, aby se vrátil ke spuštění programu. Viz man ps pro ostatní stavy procesu.

V závislosti na vašem jádru existuje plánovač procesů , který sleduje runqueue procesů připravených ke spuštění. Spolu s plánovacím algoritmem říká jádru, který proces má přiřadit kterému CPU. Je třeba zvážit procesy jádra a uživatelské procesy. Každému procesu je přidělen časový úsek, což je část času CPU, kterou může používat. Jakmile proces využije celý svůj časový úsek, označí se jako prošlý a v plánovacím algoritmu má nižší prioritu.

V jádru 2.6 , existuje O(1) plánovač časové složitosti , takže bez ohledu na to, kolik procesů máte spuštěných, přiřadí CPU v konstantním čase. Je to však složitější, protože 2.6 zavedlo preempci a vyvažování zátěže CPU není snadný algoritmus. V každém případě je to efektivní a CPU nezůstanou nečinné, když budete čekat na I/O.


Když proces potřebuje načíst data z disku, efektivně přestane běžet na CPU, aby nechal běžet ostatní procesy, protože dokončení operace může trvat dlouho – minimálně 5 ms vyhledávacího času pro disk je běžné a 5 ms je 10 milionů Cykly CPU, věčnost z pohledu programu!

Z pohledu programátora (také řečeno „v uživatelském prostoru“) se tomu říká blokování systémového volání . Pokud zavoláte write(2) (což je tenký obal libc kolem stejnojmenného systémového volání), váš proces se přesně nezastaví na této hranici; pokračuje v jádře a spouští kód systémového volání. Většinou to jde až ke konkrétnímu ovladači řadiče disku (název souboru → souborový systém/VFS → blokové zařízení → ovladač zařízení), kde je příkaz k načtení bloku na disku odeslán správnému hardwaru, což je velmi rychlý provoz po většinu času.

POTOM se proces uvede do režimu spánku (v prostoru jádra se blokování nazývá spánek – z hlediska jádra není nikdy nic „blokováno“. Jakmile hardware konečně načte správná data, bude probuzen a proces bude označen jako spustitelný a bude naplánováno. Plánovač nakonec proces spustí.

Nakonec v uživatelském prostoru blokovací systémové volání vrátí se správným stavem a daty a tok programu pokračuje.

Většinu I/O systémových volání je možné vyvolat v neblokovacím režimu (viz O_NONBLOCK v open(2) a fcntl(2) ). V tomto případě systém okamžitě zavolá return a pouze hlásí odeslání diskové operace. Programátor bude muset později explicitně zkontrolovat, zda byla operace dokončena, úspěšně nebo ne, a načíst její výsledek (např. s select(2) ). Toto se nazývá asynchronní programování nebo programování založené na událostech.

Většina odpovědí zde zmiňuje stav D (který se nazývá TASK_UNINTERRUPTIBLE v názvech stavu Linux) jsou nesprávné. D stav je speciální režim spánku, který se spouští pouze v cestě kódu prostoru jádra, když tuto cestu kódu nelze přerušit (protože by to bylo příliš složité na programování), s očekáváním, že se zablokuje jen na velmi krátkou dobu. Věřím, že většina „stavů D“ je ve skutečnosti neviditelná; mají velmi krátkou životnost a nelze je pozorovat pomocí vzorkovacích nástrojů, jako je „top“.

V několika situacích se můžete setkat s nezničitelnými procesy ve stavu D. NFS je tím pověstné a mnohokrát jsem se s tím setkal. Myslím, že existuje sémantický konflikt mezi některými cestami kódu VFS, které předpokládají, že se vždy dostanou na místní disky a rychlou detekcí chyb (na SATA by časový limit chyby byl asi 100 ms), a NFS, který ve skutečnosti stahuje data ze sítě, která je odolnější a má pomalé zotavení (běžný časový limit TCP 300 sekund). Přečtěte si tento článek o skvělém řešení představeném v Linuxu 2.6.25 s TASK_KILLABLE Stát. Před touto érou existoval hack, kde jste mohli skutečně posílat signály klientům procesu NFS odesláním SIGKILL do jádra jádra rpciod , ale zapomeňte na ten ošklivý trik.…


Linux
  1. Rychlejší spouštění Linuxu

  2. Time Sync Linux

  3. Proces spouštění Linuxu

  1. Jak zabít proces zombie na Linuxu

  2. Time Sync Linux

  3. Linux CreateProcess?

  1. Najděte čas provedení příkazu nebo procesu v systému Linux

  2. Jak nainstalovat vtop na Linux

  3. Vytvoření démona v Linuxu