[C] Strano comportamento processo

Linguaggi di programmazione: php, perl, python, C, bash, ecc.

[C] Strano comportamento processo

Messaggioda gila75 » giovedì 13 settembre 2018, 20:24

Per lo studio dei socket, mi sono messo ad approfondire e ripassare un po' i processi.
Mi sono imbattutto in uno strano comportamento che non riesco a capire.
In poche parole, sono 2 cicli while infiniti.
Uno genera i figli, l'altro è un ciclo che contiene quello del figlio.
All'uscita del processo, mi aspetto che il controllo torni al main, che tramite wait() aspetta...e via daccapo.
Ma non è così.
Codice: Seleziona tutto


#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
   int pid,x,status;
   while (1)
   {   
      while (1) // ciclo infinito di figli
      {
         pid=fork();         
         if (pid==0)
         {
            sleep(5);
            printf (" padre %d figlio %d\n", getppid(), getpid());
            exit(0);
         }
      
         
      }
//*************MAIN*****************
      if (pid>0)
      {
         x=wait(&status);
         printf ("pid %d stato %d\n", x, status);
      }
   }
   return 0;
}
   

 

 


Mi va in un ciclo infinito, e continua a creare figli.
Una sorta di fork bomb.
Cosa sbaglio ? con un while solo, la cosa si sistema. Ma in generale, se ho più cicli infiniti innestati, come faccio?
Non capisco.
Attenzione a lanciarlo, a me una volta mi ha inchiodato il pc.
Ultima modifica di gila75 il sabato 15 settembre 2018, 21:54, modificato 1 volta in totale.
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686

Re: [C][ Strano comportamento processo

Messaggioda DPD- » venerdì 14 settembre 2018, 12:12

Così come lo hai scritto la parte dopo il commento //*************MAIN***************** non verrà mai eseguita perché non c'è modo di uscire dal while più interno.
La funzione wait semplicemente aspetta che un figlio muoia (non che tutti muoiano). Non viene automaticamente spostato il program counter alla riga dove la invochi quando un figlio muore.
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda DPD- » venerdì 14 settembre 2018, 12:14

gila75 Immagine ha scritto:con un while solo, la cosa si sistema.

immagino togliendo il while interno facendo in modo che il wait venga eseguito


gila75 Immagine ha scritto:Ma in generale, se ho più cicli infiniti innestati, come faccio?

In questo caso cosa ti servono i due while innestati?
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda gila75 » venerdì 14 settembre 2018, 17:42

Così come lo hai scritto la parte dopo il commento //*************MAIN***************** non verrà mai eseguita perché non c'è modo di uscire dal while più interno.


Ciao :) infatti, l'inghippo è propio quello: credevo che con exit(0) il controllo fosse restituito al main indipendentemente dalla profondidà dei cicli
annidati. Un super break se me lo concedi, invece no. Resta inglobato. Ero convintissimo di uscire.

In questo caso cosa ti servono i due while innestati?


In un programma client/server che ho trovato in rete, ci sono 2 while annidati. Uno gestisce accept, e l'altro (tramite un figlio) la ricezione dati.
Mi sono accorto che alla wait() che è nel main non ci si arriva mai. E secondo me non è corretto.
Il programma che ho postato, è grosso modo una semplificazione di quel programma client/server, se non ho fatto errori.
Se lo lanci ti accorgi facendo top in un altro terminale che il pc si popola di processi zombie, finchè provando ad aprire un altro terminale o qualsiasi
processo, la fork fallisce.
Volevo appunto appurare la non correttezza di quel programma.
Facendo un processo figlio e uno padre, con 2 while sono fregato, stando al programma che ho messo. Viceversa 2 figli posso gestire la cosa.
Anche se un figlio cicla all'infinito, non ho problemi. Non so se sono stato chiaro.
Grazie per la spiegazione, sono un po' confuso. Ci avrei giurato che exit mi facesse uscire.
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686

Re: [C][ Strano comportamento processo

Messaggioda DPD- » venerdì 14 settembre 2018, 17:54

gila75 Immagine ha scritto:credevo che con exit(0) il controllo fosse restituito al main indipendentemente dalla profondidà dei cicli
annidati.

La exit chiude il processo corrente (figlio) senza intaccare l'esecuzione del padre che continuerà a ciclare nel for interno da cui non ha modo di uscire.
gila75 Immagine ha scritto:In un programma client/server che ho trovato in rete, ci sono 2 while annidati. Uno gestisce accept, e l'altro (tramite un figlio) la ricezione dati.
Mi sono accorto che alla wait() che è nel main non ci si arriva mai. E secondo me non è corretto.
Il programma che ho postato, è grosso modo una semplificazione di quel programma client/server, se non ho fatto errori.

Se è così allora quel programma non è scritto correttamente.
Sicuro non ci sia qualcosa per cui possa uscire dal ciclo? È veramente infinito? Se è veramente così allora è sbagliato.
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda DPD- » venerdì 14 settembre 2018, 18:01

Per chiarire un po' ho fatto un semplice schema dell'esecuzione logica di un padre e un figlio.
Se ho capito bene tu pensavi che invocato l'exit si andasse al wait (freccia blu), ma non è così.
Il wait deve essere raggiunto dalla freccia rossa (che manca dato che non esiste una condizione di uscita dal ciclo) ed il wait aspetta che il figlio termini (apparentemente sembra che ci sia la freccia blu, anche se non c'è)

Spero di essere stato chiaro e non averti fatto ancora più confusione :D , purtroppo questo è un argomento complesso da cpaire
Allegati
pid.png
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda gila75 » venerdì 14 settembre 2018, 19:32

Si, chiaro. Io interpretavo exit al pari di return che se ne infischia dei cicli annidati. Pensavo che mi indirizzasse dritto al padre, nel mio caso il main.
Grazie.
Quindi se ho 2 while concatenati padre e figlio non possono andare bene come sospettavo, giusto ?
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686

Re: [C][ Strano comportamento processo

Messaggioda DPD- » venerdì 14 settembre 2018, 20:51

gila75 Immagine ha scritto:Si, chiaro. Io interpretavo exit al pari di return che se ne infischia dei cicli annidati. Pensavo che mi indirizzasse dritto al padre, nel mio caso il main.

L'exit fa lo stesso che il return usato nel main.
Occhio però che il padre sta eseguendo il ciclo (che appartiene al main anche se non è il "main" che dici tu)

gila75 Immagine ha scritto:Si, chiaro. Io interpretavo exit al pari di return che se ne infischia dei cicli annidati. Pensavo che mi indirizzasse dritto al padre, nel mio caso il main.
Grazie.
Quindi se ho 2 while concatenati [...] non possono andare bene come sospettavo, giusto ?

Si si può: basta inserire una condizione di uscita dai cicli

gila75 Immagine ha scritto:Si, chiaro. Io interpretavo exit al pari di return che se ne infischia dei cicli annidati. Pensavo che mi indirizzasse dritto al padre, nel mio caso il main.
Grazie.
Quindi se ho 2 while concatenati padre e figlio

Non si chiamano while padre e while figlio. Padre e figlio sono i processi ed entrambi (condividono lo stesso codice) hanno i 2 while
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda gila75 » venerdì 14 settembre 2018, 22:14

E' vero, forse basta un break nel while interno ed esternamente la exit che mi va al padre. Devo provare.
E' la prima volta che cerco di studiare i processi in modo un po' serio, e non sono cosi' facili.
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686

Re: [C][ Strano comportamento processo

Messaggioda gila75 » sabato 15 settembre 2018, 18:41

Così dovrebbe essere corretto:
Codice: Seleziona tutto
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
   int pid,x,status;
   while (1)
   {   
      while (1) // ciclo infinito di figli
      {
         pid=fork(); 
         if (pid==-1)
         {
            puts ("fork error");
            return -1;
         }       
         if (pid==0)
         {
            //sleep(0);
            printf (" padre %d figlio %d\n", getppid(), getpid());
            exit(0);
         }
         break;
      }
      
//*************MAIN*****************
      if (pid>0)
      {
         x=wait(&status);
         printf ("pid[%d] Stato Uscita: %d\n", x, status);
      }
   }
   return 0;
}
   

 

 

Arrivo sempre al main dove il figlio terminato viene raccolto da wait() evitando il popolarsi di zombi
Giusto?
In definitiva la exit come l'ho usata mi funziona come break, mi esce dal loop più interno. Non me lo aspettavo
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686

Re: [C][ Strano comportamento processo

Messaggioda DPD- » sabato 15 settembre 2018, 18:50

Il break che hai aggiunto viene raggiunto alla prima iterazione del while annullando di fatto il ciclo infinito interno.
Il codice di sopra funziona esattamente come questo:
Codice: Seleziona tutto
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main(void)
{
   int pid,x,status;
   while (1)
   {   
         pid=fork();
         if (pid==-1)
         {
            puts ("fork error");
            return -1;
         }       
         if (pid==0)
         {
            //sleep(0);
            printf (" padre %d figlio %d\n", getppid(), getpid());
            exit(0);
         }
     
//*************MAIN*****************
      if (pid>0)
      {
         x=wait(&status);
         printf ("pid[%d] Stato Uscita: %d\n", x, status);
      }
   }
   return 0;
}
Dettagli del mio computer: DELL Inspiron 3542 · Kubuntu 18.04 x64 KDE Plasma 5
Intel i5-4210U 1,7GHz × 4 thread · 8 GB DDR3L 1600MHz Ram + 8 GiB swap · Intel HD Graphics 4400
            
DPD-
Scoppiettante Seguace
Scoppiettante Seguace
 
Messaggi: 450
Iscrizione: marzo 2011
Località: Friuli
Desktop: KDE Plasma 5
Distribuzione: Kubuntu 18.04 (64 bit)
Sesso: Maschile

Re: [C][ Strano comportamento processo

Messaggioda gila75 » sabato 15 settembre 2018, 20:30

É vero, torno al codice che avevo già provato con un while solo. Allora non lo so....
Avatar utente
gila75
Imperturbabile Insigne
Imperturbabile Insigne
 
Messaggi: 2530
Iscrizione: gennaio 2013
Località: Airuno(Lecco)
Desktop: ubuntu-2d
Distribuzione: Ubuntu 12.04.2 LTS i686


Torna a Programmazione

Chi c’è in linea

Visualizzano questa sezione: 0 utenti registrati e 4 ospiti