Exercicis de Creació de processos en C

Creació de processos en C
  1. 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:

    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

Nota

El valors del PID són només exemples i poden variar en cada execució.

  1. Quantes vegades s’imprimirà OS?

    int main(){
        if(execel("bin/ls","ls",NULL) == -1){
        perror("execl");
        }
        printf("OS\n");
        return 0;
    }
  2. 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

  1. 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

  1. 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 a en el procés pare i en el procés fill?
    • S’imprimirà la mateixa adreça de memòria per a a en 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?
  2. 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;
    }
  3. 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);
        }
    }
  4. 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

    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()