Skomplikowany fork


(Damian True) #1
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main(){
	char t[] = "axcxexgxixkx";
	int i=0, p=getpid(); <--1
	while(i<9) {            
		if(!fork()) { <--2
			i++;
			t[i]='+';
			break;
		}
	i++;
	}
if(p!=getpid()){ <--3
	exit(0);
}
else{
	while(-1!=wait(NULL)); <--4
        printf("%s\n",t);
}
return 0;
}

Miałem takie zadanie na teście. Miałem napisać co się wypisuje na ekranie. Po skąpilowaniu wyszło mi axcxexgxixkx jednak nie wiem za bardzo skąd to się wzieło.

1) tu rozumiem jest pobranie pid procesu głównego

2) Tutaj nie wiem co się za bardzo dzieje. Czy do tego ifa wchodzą tylko procesy potomne ?

3) Tutaj wszystkie procesy potomne są zamykane

4) Tutaj proces główny (p1) czeka aż wszystkie procesy potomne sie wykonają ?

 

Jeśli się gdzieś mylę to proszę mnie poprawić ponieważ nie jestem pewien za bardzo jak to się dzieje w tym programie


(enedil) #2

Poza punktem 2. Wszystko jest poprawne.

int fork(void);

Zwraca 0 gdy jest w procesie rodzica, a zwraca pid dziecka gdy jest w procesie dziecka. Zatem ten if wykona się jeżeli fork() realizuje go false, czyli jest w procesie rodzica.


(Damian True) #3

Jeśli wchodzi tam tylko rodzić to pętla while zostaje zatrzymana przy break a wtedy i=1 ? A przecież + nie pokazuje się na żadnej pozycji. Nie wiem co się stanie w tej pętli while.


(enedil) #4

Skoro zmieniasz t tylko w procesie rodzica, a drukujesz tylko w procesie dziecka, to czemu się dziwisz? Sprawdź na przykładzie:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>

int main()
{

    int i = 0, p = getpid(); //<--1
    while(i < 9) {
        if(!fork()) {
            char t[] = "axcxexgxixkx"; //<--2 // Przeniosłem deklarację `t` di procesu rodzica.
            i++;
            t[i] = '+';
            break;
        }
        i++;
    }
    if(p != getpid()){ // <--3
        exit(0);
    }
    else {
        while (-1 != wait(NULL))
            ; //<--4
        printf("%s\n", t); // W tej linii wyskakuje błąd kompilacji braku deklaracji zmiennej `t`.
    }
    return 0;
}

(Rolek0) #5

Nieprawda.

Przy powodzeniu: zwraca PID dziecka w procesie rodzica, oraz 0 w procesie dziecka.

Przy niepowodzeniu: zwraca -1 w procesie rodzica.

Odwrotnie.


(enedil) #6

Fakt. Pomyliłem się. W każdym razie ogólny sens jest taki sam.


(Damian True) #7

Czyli podsumowując rodzic nie wchodzi do ifa (2) tylko jego dzieci tam wchodzą. Dzieci zmieniają zmienną t ale rodzic ma niezmienioną swoją zmienną t więc wypisuje oryginalny tekst rodzica. Dobrze zrozumiałem?


(enedil) #8

Tak. O to chodziło.