Newsgroup: it.comp.www.php
Titolo: fork e javascript

Ho un problema con ajax e le fork. Ho uno script javascript che esegue 
una chiamata HTTP con l'oggetto xmlHttpRequest ad uno script php. Di 
ritorno da questo script produco in output una stringa. Se nello script 
php eseguo delle fork, ho una risposta quasi immediata a livello 
callback Ajax penso causato dal primo processo figlio che termina. Il 
problema che il processo padre quando finisce mi produce l'ouput ma 
questo non viene mai intercettato dalla callback di ajax.

chri ha scritto:

Perche' esegui delle fork?
-- 
Vuoi distribuire il tuo sito web su CD/DVD?
Prova 
http://www.dwebpro.com/
Vuoi diventare un esperto analista PHP/MySQL?
Vieni a fare uno stage con noi: 
http://www.creativepark.it/stage/

 tipicamente delle connessioni a web server.
Potresti chiarire meglio cio' che stai facendo?
Come implementi le fork in PHP?
Che cosa ti aspetti di ottenere da tale codice?


 tipicamente delle connessioni a web server.
Non ho mai usato fork in PHP, ma in generale devi usare pcntl_waitpid() 
nel processo padre per sincronizzare tutti i fork, prima di mandare 
l'output al browser.
Bye.

 php eseguo delle fork,
Dai retta a un bischero: il forking dei processi lascia che sia apache
a farlo per te. Diciamo che ci sono buone probabilità che usi dei
metodi un capellino più robusti, e soprattutto meglio integrati con il
protocollo HTTP, di quelli che puoi implementare tu dentro uno script
PHP.
bye!

 a farlo per te. 
Cosa intendi che apache lo fa per me? Come allora far eseguire più 
processi contemparaneamente e poi raccoglierne i risultati?


 processi contemparaneamente e poi raccoglierne i risultati?
Basta fare più richieste HTTP. Per ognuna apache farà il fork ad un
processo (o thread, dipende che modello di multiprocessing usi) php
separato, e trasmetterà le risposte relative.
Se ti fai il fork da solo, ammesso che tutto funzioni, come speri che
il client capisca cosa fare se gli arrivano n risposte relative ad una
sola request http? Bene che ti vada prenderà le prima, le altre sono
in ogni caso cestinate.
bye!

 separato, e trasmetterà le risposte relative.
Ho provato, ma le richieste HTTP con l'oggetto xmlHttpRequest vengono 
inviate simultaneamente dal browser ma vengono sequenzializzate dal 
server. In pratica non c'è multitasking!


 server. In pratica non c'è multitasking!
Sei sicuro?
Usi sempre lo stesso xmlHttpRequest o ne hai istanziato uno per ogni 
richiesta?
Nel primo caso, vengono serializzate dal browser e non dal server.
Nel secondo caso, forse e` un'impostazione del server che non accetta piu` 
di una connessione alla volta dallo stesso IP, ma mi pare strano (il sito 
sarebbe lentissimo a caricarsi). Almeno 2 o 4 connessioni contemporanee 
sono ammesse, di solito.
Bye.

 richiesta?
Ne istanzio uno per ogni richiesta!!! vengono serializzate dal server, 
sono sicuro, ho tracciato i tempi con un log!


 server. In pratica non c'è multitasking!
non sarà forse che è il browser che "sequenzializza", mi pare che non si
possano fare più di 2 richieste contemporanee
poi probabilmente stai usando un qualche framwork "ajax" il quale
"sequenzializzerà" lui...

 possano fare più di 2 richieste contemporanee
Questo è un aspetto da approfondire... ma penso che se gli oggetti 
istantiati sono diversi il browser fa partire più richieste 
contemporaneamente!


 contemporaneamente!
E' meglio che approfondisci. Ho fatto un semplice test in Firefox 2.0 e
anche se crei due oggetti XMLHttpRequest() distinti, le richieste
vengono serializzate lato client ed eseguite una dopo l'altra.


 contemporaneamente!
E ma non è così, fai un po' di test e vedrai...
ma non avevi detto di aver guardato i log degli accessi al server?

Ugo ha scritto:

Si lato server ho notato la non contemporaneità!

 
Morale, non si può avere multitasking senza le fork! Giusto?

 Morale, non si può avere multitasking senza le fork! Giusto?
Potresti chiarire cosa intendi per multitasking e fork?


 
Intendo avere piů processi che girano contemporaneamente nello schema 
classico di consumatore e produttore! Tipo processo padre che aspetta 
che i figli abbiano completato il loro lavoro e ne prende i risultati!

 i risultati!
Sei conscio che un browser non e' l'ambiente piu' adatto per
implementare un sistema di multitasking cosi' come Javascript non e'
certamente il linguaggio migliore?
Sei davvero sicuro di voler implementare quello che stai tentando di
fare (non si e' ancora capito cosa sia realmente) in una applicazione
web?


 server. In pratica non c'è multitasking!
No, apache non serializza alcunchè; al limite ti rimbalza se hai
raggiunto il MAX_CONNECTION, ma non ritarda mai la risposta ad una
richiesta. Probabilmente partono proprio in maniera sequenziale, come
ti hanno già fatto notare.
bye!

 
Infatti la domanda era sulla chiusura della connessione ajax all'uscita 
del primo processo figlio. Il multitask lo eseguo con le fork Unix.


 fork Unix.
Ieri ti ho chiesto "Come implementi le fork in PHP?", potresti
rispondere?
Se non ci fai vedere il codice che stai utilizzando difficilmente
qualcuno potra' dirti per quale motivo la connessione viene chiusa
prima che l'ultimo processo figlio abbia completato l'esecuzione.


 
ok, il codice è un pò lungo per cui cerco di sintetizzare:
for($k=1; $k<=$numProcess; $k++){
    $pId = pcntl_fork();
    if(!$pId){
          // child
          DoChildProcess(...);
          posix_kill(posix_getpid(), SIGTERM);
          exit;
    }
    $aPid[$k-1] = $pId;  // memorizzo i pid dei figli
  }
...
...
// qui il padre cicla e va a vedere quando i figli hanno finito.
Il punto saliente è la posix_kill e la exit!!! appena un processo figlio 
termina mi termina anche la connessione ajax. Ho provato anche ad 
implementare la posix_kill alla fine dal processo padre ma senza 
risultati!!!


chri ha scritto:

Ah dimenticavo, questo codice viene eseguito da una chiamata HTTP ajax!!!


 }
Altrimenti aggiungi calcoli per niente ad ogni thread.
E poi, qui sotto:
if (!$pId) {
 foreach ($aPid as $pid) {
   pcntl_waitpid($pid, $status);
   // controlla $status
 }
 // restituisce l'output
}
Poi, naturalmente, devi usare IPC per passare l'output dai figli al padre. 
Non sperare che basti un print sui figli. :)
Come da manuale, puoi usare fork solo se PHP viene eseguito come CGI, 
perche` come modulo di Apache non e` affidabile.
Bye.

 ajax!!!
E' ininfluente, e' sempre una richiesta HTTP.


 }
Ecco è qui il punto! La pcntl_waitpid($pid, $status) non cattura l'ouput 
della exit(). Mi spiego, io devo monitorare se un filgio ha finito e non 
posso ucciderlo (posix_kill()) per farlo terminare proprio perchè ho 
delle poilitiche IPC (semafori e memoria condivisa). Per cui se dopo che 
il figlio ha terminato il lavoro e ha scritto in memoria condivisa i 
dati per il padre esce con exit($n):
for($k=1; $k<=$numProcess; $k++){
      $pId = pcntl_fork();
      if(!$pId){
            // child
            DoChildProcess(...);
            exit(1);
      }
La pcntl_waitpid($pid, $status) non cattura MAI l'uscita!!!


 Ah dimenticavo, questo codice viene eseguito da una chiamata HTTP ajax!!!
Devo ancora capire come puoi sperare di sincronizzare una richiesta
HTTP con "n" risposte. Se nella pagina hai "n" chiamate ajax, con quel
codice lanci n^2 processi (che imho non faranno quello che ti aspetti
in ogni caso).
bye!

risultati!!!
Prova a chiudere lo stdio sui figli... non si sa mai.
Altrimenti non ti rimane che far scrivere in un vettore IPC lo stato,
e quando un figlio ha finito setta il proprio stato a 1 - ed entra in
un ciclo nullo di sleep(1). Quando tutti sono a 1, e' il padre che si
mette addosso i panni di Erode.
Leonardo
-- 
The stars have not dealt me the worst they could do:
My pleasures are plenty - my troubles are two.
But oh!, my two troubles, they reave me of rest:

Si è proprio quello che faccio ho un array di stato in memoria condivisa!!!
Uhm. A me pareva di vedere i figlioli che si auto-inviavano un SIGTERM :-)


Si vero! ma dopo che è avvenuta una segnalazione IPC dal padre al figlio.
No, leva quel pezzo. Il padre controlla, ogni tot, lo stato dei figli, e
quando TUTTI hanno finito assembla il risultato, lo manda al client, poi
come ULTIMA cosa termina i figli. Dovrebbe andare.
