Visualizzazione dei risultati da 1 a 9 su 9

Discussione: fork() in PHP

  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18

    fork() in PHP

    Salve a tutti,
    il problema che sto cercando di risolvere è il seguente.
    Ho uno script con un lunghissimo array (800 elementi) in cui ciascun elemento deve essere opportunamente elaborato per un tempo variabile da qualche millisecondo fino al caso peggiore di ben 4 secondi.
    Se fate quindi i conti, nel caso peggiore l'esecuzione del mio script durerebbe quasi un'ora!
    La soluzione è quindi sfruttare al meglio i 4 core del web server che ospita lo script effettuando un FORK su 4 figli, e far elaborare a ciascuno di esso circa 200 elementi contemporaneamente.
    Logicamente il tutto dovrebbe funzionare.
    Ho scritto un codice di prova dove l'array conta solo 47 elementi giusto per simulazione.



    codice:
    <?php 
    function esecuzione($i,$arr,$inizio,$fine){ 
    	$fp = fopen("forktest", "a");
     	for($a=$inizio;$a<=$fine;$a++) { 
    		sleep(rand(0,1)); 
    		fwrite($fp, "SONO IL FIGLIO ".$i." elaborato elemento ".$arr[$a]."\n");
    	 	} 
            fclose($fp); 
    }       
    $arr=array(); 
    $dim_arr = 46; /////////////////////////////////////CREO L'ARRAY 
    for($x=1;$x<=$dim_arr;++$x){ 	
    $arr[]=$x;
     } /////////////////////////////////////CREO GLI INDICI NEL CASO DI 4 CORE 
    $num_core=4;  
    $start_1=1; 
    $end_1=round(count($arr)/$num_core);    
    $start_2=$end_1+1; 
    $end_2=(2*$end_1);   
    $start_3=$end_2+1;
     $end_3=(3*$end_1);   
    $start_4=$end_3+1;
     $end_4=count($arr); //L'ultimo arriva fino alla fine  
    for ($i = 1; $i <= 4; ++$i) {        
         $pid = pcntl_fork();         
          if (!$pid) { 	    	   
    	switch($i) { 		
                           case 1:
       esecuzione($i,$arr,$start_1,$end_1);	 			
    case 2 : 
       esecuzione($i,$arr,$start_2,$end_2); 
    case 3 :
      esecuzione($i,$arr,$start_3,$end_3); 	
    case 4 : 
     esecuzione($i,$arr,$start_4,$end_4); 				 		} 		exit($i);       
      } 
    
     }      
    while (pcntl_waitpid(0, $status) != -1) {        
     $status = pcntl_wexitstatus($status);         
    echo "Child $status completed\n";   
      } ?>
    Adesso, qualcuno mi spiega perchè non funziona??L'output che leggo sul file forktest mi mostra che ciascun figlio esegue lo scan dell'intero array anzichè della parte che volevo assegnargli.
    Dove sbaglio?
    Grazie a tutti!!

  2. #2
    Così ad occhio... mancano i break nello switch/case
    Full Stack Developer presso Advice Lab
    Bonus Bitcoin
    Moon Bitcoin

  3. #3
    Codice PHP:
    switch($i) {         
    case 
    1:
       
    esecuzione($i,$arr,$start_1,$end_1);                 
       break;
    case 

       
    esecuzione($i,$arr,$start_2,$end_2); 
       break;
    case 
    :
      
    esecuzione($i,$arr,$start_3,$end_3);     
      break;
    case 

     
    esecuzione($i,$arr,$start_4,$end_4);                  


  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18
    Molto bene, ora funziona correttamente!!!
    Tuttavia non mi spiego il perchè l'assenza dei break avesse influito in questo modo.
    Se comunque la parte di codice terminava con il ciclo for della funzione esecuzione() perchè veniva eseguito altro codice da ciascun figlio??

  5. #5
    Perchè dopo il for l'esecuzione torna allo switch e continua l'istruzione successiva.

  6. #6
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18
    Mmmh..quindi viene eseguita l'istruzione successiva(ovvero il case($i+1)) anche se il valore $i rimane quello di prima?

  7. #7

  8. #8
    Senza i breack succede che quando $i è = 1 vengono eseguite:

    esecuzione($i,$arr,$start_1,$end_1);
    esecuzione($i,$arr,$start_2,$end_2);
    esecuzione($i,$arr,$start_3,$end_3);
    esecuzione($i,$arr,$start_4,$end_4);

    con $i = 2
    esecuzione($i,$arr,$start_2,$end_2);
    esecuzione($i,$arr,$start_3,$end_3);
    esecuzione($i,$arr,$start_4,$end_4);

    con $i = 3
    esecuzione($i,$arr,$start_3,$end_3);
    esecuzione($i,$arr,$start_4,$end_4);

    con $i = 4
    esecuzione($i,$arr,$start_4,$end_4);

    Tra parentesi... se invece di $end_1 , $start_1 e seguenti, usi degli array ($end[1],$start[1]...) ti eviti lo switch
    Full Stack Developer presso Advice Lab
    Bonus Bitcoin
    Moon Bitcoin

  9. #9
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    18
    Ottimo consiglio!!Fatto subito e perfettamente funzionante!
    Grazie mille ragazzi!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.