sequenceDiagram
autonumber
participant P as Pare · PID 100
participant F1 as Fill1 · PID 101
participant F2 as Fill2 · PID 102
P->>F1: fork → crea F1
P->>P: wait bloquejat
F1->>F1: wait retorna -1
F1->>F1: exit
F1-->>P: desbloqueja wait del PID 100, retorna 101
P->>F2: fork → crea F2
P->>P: exit
F2->>F2: exit
Exercicis de Creació de processos en C
Quants processos es creen en executar el següent codi i quina és la seqüència d’esdeveniments?
fork(); if (wait(st)>0) fork(); exit();Solució:
Aquest codi crea 3 processos en total: el procés pare i dos processos fills. La seqüència d’esdeveniments és la següent:
El valors del PID són només exemples i poden variar en cada execució.
Quantes vegades s’imprimirà OS?
int main(){ if(execel("bin/ls","ls",NULL) == -1){ perror("execl"); } printf("OS\n"); return 0; }Quantes vegades
wait(st)retorna -1?id = fork(); wait(st); //1 if (id==0) fork(); wait(st); //2 exit();Solució: En aquest cas,
wait(st)retorna -1 3 vegades. La seqüència d’esdeveniments és la següent:
sequenceDiagram
autonumber
participant P as Pare · PID 100
participant F1 as Fill1 · PID 101
participant N1 as Net1 · PID 102
P->>F1: fork → crea F1
P->>P: wait bloquejat //1
F1->>F1: wait retorna -1 //1
F1->>N1: fork → crea N1
F1->>F1: wait bloquejat //2
N1->>N1: wait retorna -1 //2
N1->>N1: exit
N1-->>F1: desbloqueja wait del PID 101, retorna 102
F1->>F1: exit
F1-->>P: desbloqueja wait del PID 100, retorna 101
P-->>P: wait retorna -1 //2
P->>P: exit
Quantes vegades
wait(st)retorna -1?id = fork(); wait(st); //1 if (id!=0) fork(); wait(st); //2 exit();Solució: En aquest cas,
wait(st)retorna -1 3 vegades. La seqüència d’esdeveniments és la següent:
sequenceDiagram
autonumber
participant P as Pare · PID 100
participant F1 as Fill1 · PID 101
participant F2 as Fill2 · PID 102
P->>F1: fork → crea F1
P->>P: wait bloquejat //1
F1->>F1: wait retorna -1 //1
F1->>F1: wait retorna -1 //2
F1->>F1: exit
F1-->>P: desbloqueja wait del PID 100, retorna 101
P->>F2: fork → crea F2
P->>P: wait bloquejat //2
F2->>F2: wait retorna -1 //2
F2->>F2: exit
F2-->>P: desbloqueja wait del PID 100, retorna 102
P->>P: exit
Analitza el següent codi i respon les preguntes:
int main(void) { int a = 1; pid_t fork_ret = fork(); if (fork_ret > 0) { a++; fprintf(stdout, "Parent: int a is %d at %p\n", a, &a); } else if (fork_ret == 0) { a++;} fprintf(stdout, "Child: int a is %d at %p\n", a, &a); return 0; }- Quin és el valor de
aen el procés pare i en el procés fill? - S’imprimirà la mateixa adreça de memòria per a
aen el procés pare i en el procés fill? - S’imprimirà a la mateixa sortida estàndard (STDOUT) en el procés pare i en el procés fill?
- Quin és el valor de
Analitza el següent codi i justifica quin serà el resultat de la seva execució:
int main(void) { int* stuff = malloc(sizeof(int)); *stuff = 5; pid_t fork_ret = fork(); printf("The last digit of pi is %d\n", *stuff); if (fork_ret == 0) *stuff = 6; return 0; }Quina és la sortida del següent codi?
int main() { switch(fork()){ case 0: printf("A"); switch(fork()){ case 0: printf("B");exit(0); default: switch(fork()){ case 0: printf("C");exit(0); default: wait(&st);wait(&st);exit(0); } wait(&st); } default: wait(&st); exit(0); } }Indiqueu quin és el resultat de l’execució del següent codi. Nombre de processos creats, parantiu, informació de stdout, procés zombi, etc.
#define N 10 int main() { int pid = getpid(); for (int x=0; x<N x++) { switch(fork()) { case 0: if ( (pid%2) == 0 ) printf("Pid Fill: %d\n", getpid()); exit(0); //3 break; default: if ( (pid%2) !== 0 ) exit(0); //2 break; } } wait(NULL); exit(0); //1 }Solució:
El comportament del codi depèn de si el pid del procés pare és parell o senar:
- Cas parell:
sequenceDiagram
autonumber
participant P as Pare (PID parell)
participant F1 as Fill1
participant F2 as Fill2
participant Fx as ...
participant F10 as Fill10
P->>F1: fork() crea Fill1
F1->>F1: printf("Pid Fill: 101") i exit() //3
P->>F2: fork() crea Fill2
F2->>F2: printf("Pid Fill: 102") i exit() //3
P->>Fx: fork() crea FillX
Fx->>Fx: printf("Pid Fill: 10X") i exit() //3
P->>F10: fork() crea Fill10
F10->>F10: printf("Pid Fill: 110") i exit() //3
P->>P: wait()
Note over P,F10: Pare fa wait(NULL) al final i recull un fill
P->>P: exit() //1
El procés pare crea 10 fills, un a cada iteració del bucle.
Els fills acaben immediatament amb la crida a
exit(0).El pare, no fa cap
wait()dins del bucle, per tant, els fills es converteixen en processos zombis temporals.El pare únicament fa un
wait()al final del bucle, per tant, el procés pare rebra la notificació de la finalització d’un fill i acabarà.Tots els processos fills -1 acaben en estat zombi.
Tots els processos orfes fins que init els recull.
Cas senar:
sequenceDiagram
autonumber
participant P as Pare (PID senar)
participant F as Fill
participant N as Net
participant P10 as Pare 10e
participant F10 as Fill 10e
P->>F: fork() crea Fill
P->>P: exit() //2
F->>N: fork() crea Net
F->>F: exit() //2
P10->>F10: fork() crea Fill 10e
P10->>P10: exit() //2
F10->>F10: surt del bucle
F10->>F10: wait() retorna -1
F10->>F10: exit()
- En aquest cas, el pare acaba després de crear el primer fill.
- Cada iteració del bucle, el nou pare (fill iteració anterior) crea un fill i acaba.
- Es creen 10 generacions a partir del pare: P -> F -> N -> BN …
- Cap pare fa cap
wait(), per tant, tots els fills es converteixen en processos zombis. - L’últim fill executarà el
wait()i com no té fills, retornarà -1 i acabarà. - Tots els processos fills acaben en estat zombi temporal.
- Tots els processos fills esdevenen orfes fins que init els recull.