Uživatelské nástroje

Nástroje pro tento web


fork

Fork

  • fork() slouží ke spuštění další instance procesu vytvořením kopie včetně aktuálního kontextu
  • oba procesy pokračují v kódu od místa zavolání funkce fork
  • proces pozná, zda je potomek nebo rodič, podle návratové hodnoty fork
pid_t pid = fork();
 
if (pid<0) {
  // failed
}
 
if (pid == 0) {
  // child
} else {
  // parent
} 
  • pokud je ukončen rodičovský proces, z potomka se stane sirotek (orphan)
  • pokud je ukončen potomek před rodičem, stává se nemrtvým (zombie)

likvidace zombie procesů

  • zombie je proces, který skončil provádění kódu, ale zůstal zapsán v tabulce procesů, aby si rodičovský proces mohl přečíst jeho návratovou hodnotu.
  • zombie zůstává v „Terminated state“, dokud s tím rodič něco neudělá.
  • blokující wait()
    • funkce wait čeká na ukončení potomka.
    • zavoláme v kódu po vytvoření potomka. Čekání blokuje proces
  • neblokující wait()
  • zaregistrujeme handler, který při příjmu signálu SIGCHLD zavolá wait()
  • zrušení potřeby wait()
    • zaregistrujeme handler SIG_IGN a nastavíme flag SA_NOCLDWAIT
    • systém pak ukončené potomky rovnou zapracovává
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sa.sa_flags = SA_NOCLDSTOP | SA_NOCLDWAIT;
sigaction(SIGCHLD, &sa, NULL);
  • double fork
    • vytvoříme potomka a v něm dalšího.
    • prvního potomka zabijeme, čímž uděláme z potomka dalšího sirotka
    • tohle řešení se prý používá nejčastěji, protože přináší další výhody jako odpojení stdin/out/err od mateřského procesu atd.
pid_t pid1, pid2;
pid1 = fork();
 
if (pid1 == -1) {
	// fork failed
	exit(1);
}
 
if (pid1 == 0) {
	// child
	pid2 = fork(); //second fork
	if (pid2 == -1) {
		// fork failed
		exit(1);
	} 
 
	if (pid2 == 0) {
		// child
		ret = system(cmd);
		exit(ret);
	} 
 
	// parent
	exit(0);
} 
 
//parent
waitpid(pid1, &ret, 0);
fork.txt · Poslední úprava: autor: 127.0.0.1

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki