Newsgroup: it.comp.os.linux.development
Titolo: Problema con i thread

Nel mio programma che gira in ambiente linux con l'uso di un database 
MYSQL eseguo più volte due thread con due applicazioni differenti 
incomprensibilemente dopo un certo numero di volte il programma mi si 
blocca per la sopraggiunta di un SIGPIPE. Vi posto il messaggio 
restituitomi da gdb:
Program received signal SIGPIPE, Broken pipe.
0x4016ce18 in write () from /lib/libc.so.6
vi prego respondetemi sono bloccato in questo punto e non riesco a 
capire come proseguire.
Il sorgente incriminato è:
         pid=fork();
         if(pid==0){
             fprintf(LogFp,"[Cross]: parametri: File:%s, strnumpar=%s, 
prob=%s, id=%s, outfile=%s\n",filename,strnumpar,prob,strid,OUTRESFILE);
 
if(execl("./appcross","appcross",filename,strnumpar,prob,strid,OUTRESFILE,NULL)<0){
                fprintf(LogFp,"Can't execute appcross...\n");
                return 0;
             }
          }
          else if(pid>0){
             pid=waitpid(pid,&status,0);
             if(WIFEXITED(status)){
                fprintf(LogFp,"appcross exited with status 
%d...\n",WEXITSTATUS(status));
                if(WEXITSTATUS(status)==0){
                   asprintf(&resfilename,"%sres%d.dat",OUTRESFILE,id);
                   if(addtonewpop(mysql,numpar,resfilename,p_id)==0) 
return 0;
                }
                else
                   fprintf(LogFp,"Problem when execute appcross...\n");
             }
             else if(WIFSIGNALED(status))
                fprintf(LogFp,"Error: appcross terminated with signal 
%d...\n",WTERMSIG(status));
          }
          else{
             fprintf(LogFp,"Unable to fork process...\n");
             return 0;
          }
          asprintf(&prob,"%f",mut_pb);
          pid=fork();
          if(pid==0){
             fprintf(LogFp,"[Mut]: parametri: File:%s, strnumpar=%s, 
prob=%s, id=%s outfile=%s\n", filename, strnumpar, prob, strid, OUTRESFILE);
             if(execl("./appmut","appmut",filename,strnumpar,prob,strid, 
OUTRESFILE,NULL)<0){
                fprintf(LogFp,"Can't execute appmut...\n");
                return 0;
             }
          }
          else if(pid>0){
             pid=waitpid(pid,&status,0);
             if(WIFEXITED(status)){
                fprintf(LogFp,"appmut exited with status 
%d...\n",WEXITSTATUS(status));
                if(WEXITSTATUS(status)==0){
                   asprintf(&resfilename,"%sresmut%d.dat",OUTRESFILE,id);
                   if(addtonewpop(mysql,numpar,resfilename,p_id)==0) 
return 0;
                }
                else
                   fprintf(LogFp,"Problem when execute appmut...\n");
             }
             else if(WIFSIGNALED(status))
                fprintf(LogFp,"Error: appmut terminated with signal 
%d...\n",WTERMSIG(status));
          }
          else fprintf(LogFp,"Unable to fork process...\n");

 blocca per la sopraggiunta di un SIGPIPE
Presumendo che LogFp si riferisca ad un file regolare, nel pezzo di
sorgente che hai postato non mi par di vedere nulla di ovvio che possa
essere la causa del problema: un processo riceve SIGPIPE quando cerca di
scrivere su una pipe/socket che è stata chiusa all'altra estremità.
Per cui occorre capire:
a) qual è questa pipe/socket aperta su cui il tuo processo scrive
   (a naso: la connessione a MySQL?)
b) come mai l'altra estremità viene chiusa senza che il tuo processo
   se lo aspetti 
Faccio un'ipotesi (tutta da verificare): prima di forkare hai la
connessione al DB aperta, la libreria client di MySQL forse ti fa qualche
gioco strano sottobanco, del tipo usa alarm(2) e ti installa un signal
handler su SIGALARM per farsi due chiacchiere col DB server di quando
in quando (del tipo "sei vivo?" "sono vivo!")
Tra fork(2) e execl(2) c'è un piccolo spazio in cui ci sono due processi
distinti che hanno la stessa socket/pipe con cui parlare al DB e gli
stessi signal handler installati, per cui potrebbe succedere che entrambi
cerchino di parlare contemporaneamente al DB server, al quale arriva un
mix dei due messaggi. 
Il DB server a questo punto non ci capisce più nulla, ti chiude la
connessione in faccia, la parte client del tuo programma non se lo
aspetta, prova comunque a scrivere con l'altra estremità chiusa e
giustamente gli arriva un bel SIGPIPE che per default fa terminare il
processo.
Io proverei col chiudere la connessione al DB prima di forkare, e a
riaprirla dopo che i processi figli son entrambi terminati. Magari è
paranoia e basta, ma non saprei spiegarmelo in altro modo.
PS: quando usi fork(2), crei processi, non thread.
-- 
  |   \    \  | ___|_  |_  |  ianezz a casa sua... :-)
  |  _ \  | \ | _|    /   /   Verba volant, scripta
 _|_/  _\_|  _|____|___|___|  manent, data corrupted