Programování pod Linuxem pro všechny (9)

19. 3. 2004
Doba čtení: 3 minuty

Sdílet

V dnešním dílu se podíváme na plánování procesů pomocí funkce a příkazu nice. Najdete zde také výpis nejpoužívanějších signálů a naučíte se signály odesílat procesům.

Plánování procesů

Operační systém Linux umožňuje zpracovávat více procesů najednou. Pokud máte k dispozici jen jeden procesor, může zpracovat kód jen jednoho procesu za časový úsek. To, že můžete mít naráz spuštěno více programů (procesů), je umožněno neustálým přepínáním procesů v procesoru. Nikdo však nezaručuje, jak dlouho bude procesor zpracovávat proces. Pokud budete mít program realizovaný dvěma procesy, nebude zaručeno, zda bude dříve zpracován první, nebo druhý proces. Může se také stát, že volající proces bude ukončen dříve než proces volaný. Linux však garantuje, že každý proces bude nakonec spuštěn a žádný proces nebude ochuzen o systémové prostředky.

U každého procesu můžete specifikovat, jestli je více, či méně důležitý. Každému procesu je totiž přiřazeno číslo(niceness) specifikující jeho prioriu. Rozsah čísel je od 20 do –20. Čím je číslo vyšší, tím nižší prioritu proces má. Procesy mající zápornou hodnotu niceness mají vysokou prioritu a systém jim přiděluje delší čas procesoru. Implicitně mají všechny procesy přiřazno číslo 0. Zvyšovat prioritu procesu může jen uživatel root, vy svým procesům můžete prioritu jen snižovat.

Snížit prioritu spouštěného programu můžete příkazem nice, např. nice -n 10 backup. V programu můžete použít stejnojmenou funkci, jejím parametrem je celočíselná hodnota požadované priority (-20 – 20). Pokud nastane chyba (nejste root), vrací funkce –1 a nastaví proměnnou errno. Hodnotou této proměnné je EPERM, což znamená, že nemáte dostatečná práva. Funkce je deklarována v hlavičkovém souboru unistd.h.

Signály

Přehled nejpoužívanějších signálů

Jména zde uvedených signálů jsou definována pomocí maker, pokud je budete chtít používat, vkládejte do svých zdrojových kódů hlavičkový soubor signal.h. Skutečné definice jsou uvedeny v souboru /usr/include/sys/sig­num.h, který je vložen kauzulí #include do souboru signal.h. Kompletní seznam signálů naleznete v manuálových stránkách (man 7 signal).

  • SIGHUP – Systém odešle tento signál, pokud byl odpojen terminál. Spousta programátorů pokužívá signál k jiným účelům (většinou k signalizaci znovunačtení konfiguračních souborů)
  • SIGINT – Tento signál bude odeslán procesu po stisknutí kombinace kláves Ctrl+C
  • SIGILL – Tento signál obdrží proces, který se pokusil provést neplatnou instrukci. Také to může znamenat, že je poškozen zásobník programu.
  • SIGABRT – Funkce abort() tento signál odešle volajícímu procesu.
  • SIGFPE – Proces realizoval neplatnou matematickou operaci v pohyblivé řádové čárce.
  • SIGKILL – Okamžité ukončení proccesu. Signál nelze ošetřit obslužnou funkcí.
  • SIGUSR1 – Rezervováno pro využití v aplikacích.
  • SIGUSR2 – -//-
  • SIGSEGV – Program se pokusil o neplatné zpřístupnění paměti. Přístup může být uplatňován na neplanou adresu virtuálního adresového prostoru, nebo může být zakázán přístupovými právy. Signál může být také způsoben dereferencí „divokého ukazatele“.
  • SIGPIPE – Program se pokusil zpřístupnit nefunkční proud dat, jako je např. síťové spojení, které bylo uzavřeno.
  • SIGTERM – Tento signál ukončuje proces. Jedná se o implicitní signál vysílaný příkazem kill.
  • SIGCHLD – Systém tento signál odesílá při ukončení podřízeného procesu. Jeho pomocí lze asynchronně odstraňovat podřízené procesy (bude probráno v dalším dílu).
  • SIGXCPU – Proces signál obdrží, pokud překročil jemu vymezený časový limit.

Ukončování procesů – kill

Standardním způsobem se proces ukončuje buď zavoláním funkce exit(), anebo opustěním main(). Pokud chcete proces ukončit „zvenčí“, můžete použít příkaz kill (funkce, která toto obslouží z vašeho programu, má stejné jméno a proberu ji o pár řádků níž). Parametrem příkazu je signál, který se má procesu předat (implicitně SIGTERM), musí mu předcházet pomlčka („-“) a PID procesu, kterému chcete signál poslat. Tento příkaz se dá použít k odeslání jakéhokoliv signálu, stačí jen zadat jeho číslo nebo jméno. Příklad shození procesu:

% kill -KILL pid     #nebo kill -9 pid

V programu můžete použít systémové volání kill(). Pokud ho budete používat, musíte includovat do vašeho zdrojového kódu hlavičkové soubory sys/types.h a signal.h. Prvním argumentem systémového volání je PID procesu, kterému chcete poslat signál, druhým pak samotný signál. Systémové volání vrací 0, pokud vše proběhlo v pořádku. Pokud ne, vrací –1 a nastaví proměnnou errno (více viz man 2 kill).

bitcoin_skoleni

int kill(pid_t pid, int sig);

Následující tabulka ukazuje, jak mohou změnit chování různé hodnoty pid:

  • kladné číslo – Pošle signál procesu pid.
  • 0 – Odešle signál všem procesům v procesové skupině daného volajícího procesu.
  • –1 – Odešle signál všem procesům vyjma procesu volanícího.
  • menší než –1 – Signál je odeslán všem procesům v procesové skupině -pid.

To by bylo pro dnešek vše. Příště se podíváme na systémové volání wait (čekání na ukončení procesu) a povíme si něco o asynchroním odstraňování podřízených procesů (pomocí signálu SIGCHLD).

Autor článku