Problema valori PID nell'suo della fork

di il
1 risposte

Problema valori PID nell'suo della fork

Raga ho provato a creare un piccolo programmino che attivi un figlio che a sua volta ne attivi un altro gestendo le rispettive terminazioni. Ecco il codice:


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

using namespace std;

int main()
{
    pid_t pid, child1, child2;
    int parent, status1, status2, ret1, ret2;

    pid = fork();
    if(pid==0)
    {
        child1 = getpid();
        cout << "(child1) PID->" << getpid()
             << "\t parent PID->" << getppid() << endl;
        cout << "(child1) Creo un nuovo processo" << endl;
        pid = fork();
        if(pid==0)
        {
            child2 = getpid();
            cout << "(child2) PID->" << getpid()
                 << "\t parent PID->" << getppid() << endl;
            cout << "(child2) Mi metto a fare qualcosa prima di terminare" << endl;
            for(int i=0; i<2; i++)
            {
                system("sleep 1");
                cout << "(child2)..." << endl;
            }
            exit(0);
            cout << "(child2) Processo Terminato" << endl;
        }
        else
        {
            cout << "(child1) Attendo terminazione processo child2" << endl;
            cout << "(child1) Mi metto a fare qualcosa prima di terminare" << endl;
            for(int j=0; j<2; j++)
            {
                system("sleep 1");
                cout << "(child1)..." << endl;
            }
            ret1 = waitpid(child2,&status2,0);
            cout << "(child1) Mio figlio è terminato e ora "
                 << "posso terminare anche io" << endl;
            exit(0);
        }
    }
    else
    {
        cout << "(parent) PID->" << getpid() << endl;
        cout << "(parent) Attendo terminazione processo child1" << endl;
        ret2 = waitpid(child1, &status1, 0);
        cout << "(parent) Mio figlio è terminato e ora "
             << "posso terminare anche io" << endl;
        cout << "child1:" << child1 << endl;
        cout << "child2:" << child2 << endl;
            exit(0);
    }
   
   
    return 0;
}
Nel momento in cui lo lancio ho un problema in quanto le variabili child1 e child2 non contengono l'effettivo PID del processo a cui fanno riferimento e quindi non posso gestire in maniera corretta la terminazione dei due figli.

Questa è l'uscita a terminale:

(child1) PID->8129       parent PID->8128
(child1) Creo un nuovo processo
(parent) PID->8128
(parent) Attendo terminazione processo child1
(parent) Mio figlio è terminato e ora posso terminare anche io
child1:11026
child2:-1202902016
xxx@xxx-desktop:~/SCalls$ (child2) PID->8130     parent PID->8129
(child2) Mi metto a fare qualcosa prima di terminare
(child1) Attendo terminazione processo child2
(child1) Mi metto a fare qualcosa prima di terminare
(child1)...
(child2)...
(child1)...
(child1) Mio figlio è terminato e ora posso terminare anche io
(child2)...
Qualcuno mi aiuta a capire questa cosa? Sto uscnedo pazzo :S

1 Risposte

  • Re: Problema valori PID nell'suo della fork

    Ciao, per iniziare meglio spiegare il comportamento preciso della fork():
    quando questa funzione viene chiamata crea un nuovo processo clonando quello che l'ha richiamata, il che significa che crea una copia esatta del processo chiamante (comprese variabili, stack, descrittori dei file, ecc...); al processo chiamante, che diventa il padre del nuovo processo la fork() ritorna il pid del processo figlio, mantre al figlio ritorna zero.

    Ora vediamo il tuo programma:
    l'erroreche hai commesso è quello di non considerare che la fork() duplica tutte la variabili del processo padre nel filgio e che i due processi non condividono la variabili.
    #include <stdio.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <sys/wait.h>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        pid_t pid, child1, child2;
        int parent, status1, status2, ret1, ret2;
    
        pid = fork();
        // D'ora in avanti tutte le var. sono state duplicate nel processo filgio
        if(pid==0)
        {
            // Questo codice viene eseguito solo dal figlio
            child1 = getpid();  // Questa var. child1 è diversa dalla var. child1 del padre
            cout << "(child1) PID->" << getpid()
                 << "\t parent PID->" << getppid() << endl;
            cout << "(child1) Creo un nuovo processo" << endl;
            pid = fork();
            if(pid==0)
            {
                // Questo codice viene eseguito solo dal figlio
                child2 = getpid();
                cout << "(child2) PID->" << getpid()
                     << "\t parent PID->" << getppid() << endl;
                cout << "(child2) Mi metto a fare qualcosa prima di terminare" << endl;
                for(int i=0; i<2; i++)
                {
                    system("sleep 1");
                    cout << "(child2)..." << endl;
                }
                exit(0);
                cout << "(child2) Processo Terminato" << endl;
            }
            else
            {
                // Codice eseguito dal padre, la var. pid contiene il PID del figlio
                child2=pid;
                cout << "(child1) Attendo terminazione processo child2" << endl;
                cout << "(child1) Mi metto a fare qualcosa prima di terminare" << endl;
                for(int j=0; j<2; j++)
                {
                    system("sleep 1");
                    cout << "(child1)..." << endl;
                }
                ret1 = waitpid(child2,&status2,0);
                cout << "(child1) Mio figlio è terminato e ora "
                     << "posso terminare anche io" << endl;
                exit(0);
            }
        }
        else
        {
            // Codice eseguito dal padre, la var. pid contiene il PID del figlio
            child1=pid;
            cout << "(parent) PID->" << getpid() << endl;
            cout << "(parent) Attendo terminazione processo child1" << endl;
            ret2 = waitpid(child1, &status1, 0);
            cout << "(parent) Mio figlio è terminato e ora "
                 << "posso terminare anche io" << endl;
            cout << "child1:" << child1 << endl;
            cout << "child2:" << child2 << endl;  // Var. child2 non inizializzata
                exit(0);
        }
       
       
        return 0;
    }
    Così modificato dovrebbe funzionare. Ciao.
Devi accedere o registrarti per scrivere nel forum
1 risposte