Newsgroup: it.comp.lang.c
Titolo: forking di più processi

Ho provato anche ad usare il buon vecchio forking per velocizzare
l'esecuzione del programma, ma mi sfugge come si possa dividere il
carico in N processi...
Ad esempio avrei una cosa del genere
--8<---------------cut here---------------start------------->8---
main () {
     fork()
     // figlio
 
     // padre
}
--8<---------------cut here---------------end--------------->8---
Ma come faccio a lanciare N figli indipendenti?
Devo fare fork "innestati" nel processo padre ogni volta?

Avevo cominciato a scrivere una cosa di questo tipo:
--8<---------------cut here---------------start------------->8---
     if (pid == 0) {
          // child, do actual work
     }
     else {
          left_procs--;
          if (left_procs) {
               fork();
          }
     }
--8<---------------cut here---------------end--------------->8---
Ma appunto senza sapere quanti sono i processi a priori non mi sembra
fattibile..

Un ciclo for ?
for(int j = 0; j < nProcs; ++j) {
  ...
  pid_t pid = fork();
  if(pid == 0) {
    // child: fai lavoro, ed esci dal programma; prova a guardare execl per lanciare un altro programma, se ti interessa
  }
  else if(pid < 0) {
    // failure
  }
  else {
    // parent: fai quello che devi (bookkeeping...) e poi torna su al for, da cui lanci un altro child.
  }
}
e lanci il numero di processi che vuoi.
Pleg

pleg <25mV@300.K> writes:

Giusto che pirla non ci avevo pensato, ma cosa intendi per
"bookkeeping".
avendo una cosa del genere:
--8<---------------cut here---------------start------------->8---
     for (i = 0; i < NPROCS; i++) {
          game_confs[i] = game_conf;
          game_confs[i].num_simulations = game_conf.num_simulations / NPROCS;
          pid = fork();
          if (pid == 0) {
               loop(&game_confs[i]);
               output_result(game_confs[i].result, game_confs[i].num_simulations);
          }
     }
--8<---------------cut here---------------end--------------->8---
Poi lanciando il programma da shell giustamente esce subito e non riesco
a misurare il tempo di esecuzione con "time"...
In sostanza voglio solo prendere i valori ritornati in "result" e farne
la media, devo usare wait per aspettare la fine del processo quindi
giusto?

 giusto?
Beh un processo non "ritorna". Con wait (o waitpid) fai si' che il parent aspetti il child, ma un child non e' una funzione che restituisce un valore. Se 
vuoi trasferire dei dati tra child e parent (o viceversa), devi usare un qualche meccanismo di comunicazione interprocesso (pipe, fifo...).
Per bookkeeping intendo che il parent potrebbe dover tenere traccia di qualcosa riguardo i children (magari vuoi creare un array che raccoglie i pid dei 
children, o cose cosi').
Inoltre mi pare che tu stia facendo come stessi lanciando dei thread, cosa che non e'. Ad es. stai inizializzando tutti i game_confs[i] a game_conf, ma 
questo e' inutile: nel momento del fork(), ogni child ottiene il suo address space con tutti i dati replicati, quindi ogni child ha il suo game_conf, 
indipendente da tutti gli altri.
Pleg
PS: per quello che (mi sembra) vuoi fare, mi pare che lanciare thread sia molto piu' semplice che lanciare processi: vuoi solo dividere il carico di 
lavoro in pezzi uguali da mandare su diversi processori, no? Allora avere dei thread worker mi sembra il modo migliore di procedere. Il master thread 
raccoglie i risultati parziali alla fine.