Hlavní navigace

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

Jakub Matys

V dnešním dílu ukončíme kapitolu o procesech. Probereme si čekání na ukončení podřízeného procesu, procesy zombie a asynchronní odstraňování podřízených procesů.

Jak jsem v některém z předchozích dílů napsal, procesor jednotlivé procesy velmi rychle přepíná, čímž vzniká iluze, že běží více procesů najednou (paralelně). Nikdo a nic vám však nemůže zaručit, že jeden proces bude zpracován dříve než druhý, že mu bude poskytnuto přesně tolik a tolik procesorového času atd. Pokud dva procesy (nadřízený a podřízený) mají běžet nezávisle na sobě, je to v pořádku. Pokud je však nadřízený proces závislý na podřízeném, vzniká zde problém. Bude-li nadřízený proces ukončen dříve než proces podřízený, může to ohrozit funkci programu. Tento problém mohou řešit funkce ze skupiny wait, ty umožní volajícímu procesu počkat na ukončení podřízeného procesu.

Čekání na ukončení procesu – systémová volání wait

Nejjednoduší funkcí ze skupiny wait je funkce wait(). Ta zablokuje volající proces až do doby, kdy bude podřízený proces ukončen. Funkce vrací návratový kód procesu pomocí ukazatele na celočíselnou hodnotu, který lze zjistit makrem WEXITSTATUS. Pomocí makraWIFEXITED můžete zjistit, zda byl proces ukončen normálně (voláním funkce exit() nebo návratem z funkce main()), nebo zda byl ukončen na základě nezpracovaného signálu. Pokud byl ukončen signálem, použijte makro WTERMSIG, které zjistí číslo signálu, jímž byl proces ukončen.

Následující příklad spustí nový proces pomocí fork() a execvp() volaných z funkce spawn() uvedené v osmém dílu. Nadřízený proces poté čeká na ukončení podřízeného procesu voláním funkcewait() a zjistí návratový kód.

#include <sys/types.h>
#include <sys/wait.h>

int main()
{
  int child_status;
  /* Argumenty spousteneho procesu */
  char *arg_list[] = {
    "ls",
    "-l",
    "/",
    NULL
  };

  /* Spusti novy proces pomoci funkce spawn().
     Ignoruje PID, ktere jinak funkce vraci */
  spawn("ls", arg_list);

  /* Ceka na ukonceni podrizeneho procesu */
  wait(&child_status);
  if (WIFEXITED(child_status))
    printf("Podrizeny proces byl ukoncen normalne s navratovym kodem %d\n", WEXITSTATUS(child_status));
  else
    printf("Podrizeny proces byl ukoncen abnormalne\n");
  return(0);
} 

Dalšími systémovými voláními, která umožňují vyčkat na ukončení podřízeného procesu, jsou waitpid(), wait3() await4():

#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options);

#define _USE_BSD
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/wait.h>
pid_t wait3(int *status, int options, struct rusage *rusage)

pid_t wait4(pid_t pid, int *status, int options, struct rusage *rusage) 

Funkce waitpid() může být použita k čekání na specifický podřízený proces a nikoliv na libovolný (jako funkce wait()). Funkce wait3() vrací statistiku o využití CPU procesem a funkcewait4() umožňuje specifikovat další informace o procesech, na které se má čekat.

Podrobnější informace o třech výše popsaných funkcích naleznete v manuálových stránkách.

Procesy zombie

Proces zombie je proces, který byl ukončen, ale nebyl doposud „uklizen“. Odklizení provádí nadřízený proces. Tento proces automaticky provede funkci wait(), proto není před jejím voláním nutné ověřovat, zda je příslušný podřízený proces stále aktivní. Mějme příklad: program vytvoří nový proces, provade nějaké výpočty a pak na něj zavolá funkci wait(). Když však podřízený proces skončí dříve, než nadřízený proces zavolá funkci wait(), stane se z něj proces zombie. Až nadřízený proces zavolá funkci wait(), získá návratový kód podřízeného procesu, tento proces se zruší a funkce wait() se okamžitě vrátí.

Pokud ale nadřízený proces funkci wait() nezavolá, nebude podřízený proces „uklizen“. Takové procesy potom zůstávají v systému jako procesy zombie a ubírají uživatelům systémové prostředky.

Asynchronní odstraňování podřízených procesů

Když používáte podřízené procesy, je užitečné volat besprostředně po jejich spuštění funkci wait() a čekat na ukončení procesu. Často je však nutné provádět nějakou činnost paralelně s podřízenými procesy. Musíte však dát pozor, aby se nevytvářely procesy zombie. Řešením může být periodické volání funkce wait3() nebo wait4(). Tímto způsobem lze také odklidit procesy zombie, protože funkce wait3()a wait4() lze spustit s parametrem WNOHANG, který zajistí tzv. neblokující mód – funkce uklidí ukončený podřízený proces (pokud existuje) nebo se vrátí, pokud neexistuje. Nadřízený proces tedy nebude blokován jako v případě, kdybyste volali funkci wait().

Dalším způsobem, jak odstraňovat ukončené podřízené procesy, je zpracování signálu SIGCHLD. Tento signál je zasílán nadřízenému procesu pokaždé, když je podřízený proces ukončen. Stačí jej tedy pouze zachytit (podrobně se budu zabývat zpracováním signálů v některém z dalších dílů) a spustit funkci wait(). Pokud potřebujete návratový kód procesu, je nutné jeho hodnotu uložit. Protože pokud je proces jednou uklizen, není možné ji zpátky získat.

V příkladu je použita funkce clean_up(), která se zavolá pokaždé, když je zachycen signál SIGCHLD.

#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

sig_atomic_t child_exit_status;

void clean_up(int signal_number)
{
  /* Odstrani podrizeny proces */
  int status;
  wait(&status);
  /* Priradi navratovy kod globalni promene */
  child_exit_status = status;
}

int main()
{
  /* Dalsi prikazy nastavi zpracovani signalu SIGCHLD */
  struct sigaction sigchld_action;
  memset(&sigchld_action, 0, sizeof(sigchld_action));
  sigchld_action.sa_handler = &clean_up;
  sigaction(SIGCHLD, &sigchld_action, NULL);

  /* Nyni uz muzete vytvaret nove procesy, provadet vypocty ... */
  /* ... */

  return(0);
} 

Dnes by to bylo vše, doufám, že se vám nově získané informace budou hodit. V příštím dílu se začneme zabývat vlákny – vysvětlíme si, o co jde, a vytvoříme si nové vlákno.

Našli jste v článku chybu?

6. 2. 2006 21:05

Tomas (neregistrovaný)
Zase si vem, ze Apache neni lamerskej program, takze zombie nenechava a vo tom to je vem si, ze klidne jakejkoliv trivialni programek, kterej si naalokuje 1GB pameti muze pusobit problem. De vo to, ze pokud chces videt vysledek nejakyho procesu musis ho nekde mit ulozenej, dokud si ho nezpracujes.

2. 4. 2004 1:21

Jerry III (neregistrovaný)

Neni nepritel? Vem si ze by takovej apache nechaval zombie, kazdej request by zabral 2KB v pameti. Chvili si spocitej co to udela na sajtech s milionama hitu denne a pak zkus napsat znova ze zombie (a vubec jakykoli uteceni pameti, i kdyby to byl jen jeden bajt) neni nepritel.

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Podnikatel.cz: Přehledná titulka, průvodci, responzivita

Přehledná titulka, průvodci, responzivita

Podnikatel.cz: Dárkové poukazy. Vaše byznys výhra

Dárkové poukazy. Vaše byznys výhra

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Vitalia.cz: Spor o mortadelu: podle Lidlu falšovaná nebyla

Spor o mortadelu: podle Lidlu falšovaná nebyla

Vitalia.cz: Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Láska na vozíku: Přitažliví jsme pro tzv. pečovatelky

Vitalia.cz: Mondelez stahuje rizikovou čokoládu Milka

Mondelez stahuje rizikovou čokoládu Milka

Podnikatel.cz: Snížení DPH na 15 % se netýká všech

Snížení DPH na 15 % se netýká všech

Vitalia.cz: Paštiky plné masa ho zatím neuživí

Paštiky plné masa ho zatím neuživí

Podnikatel.cz: Chaos u EET pokračuje. Jsou tu další návrhy

Chaos u EET pokračuje. Jsou tu další návrhy

Podnikatel.cz: Udávání kvůli EET začalo

Udávání kvůli EET začalo

Podnikatel.cz: Udávání a účtenková loterie, hloupá komedie

Udávání a účtenková loterie, hloupá komedie

Měšec.cz: U levneELEKTRO.cz už reklamaci nevyřídíte

U levneELEKTRO.cz už reklamaci nevyřídíte

Vitalia.cz: Proč vás každý zubař posílá na dentální hygienu

Proč vás každý zubař posílá na dentální hygienu

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

Podnikatel.cz: Zavře krám u #EET Malá pokladna a Teeta?

Zavře krám u #EET Malá pokladna a Teeta?

Vitalia.cz: Znáte „černý detox“? Ani to nezkoušejte

Znáte „černý detox“? Ani to nezkoušejte

Vitalia.cz: „Připluly“ z Německa a možná obsahují jed

„Připluly“ z Německa a možná obsahují jed

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?