Newsgroup: it.comp.os.linux.development
Titolo: Programmazione concorrente

Prometto che d'ora in poi saro` piu` stringato e faro` domande one-shot, pero`
per favore per questa volta fate uno strappo alla regola e rispondete a questo
msg chilometrico. Avrete la mia imperitura gratitudine. :-)
In fondo al msg riporto un semplice programmino che ho scritto per iniziare a
far pratica con le primitive di Unix per la programmazione concorrente. In
poche parole esso avvia M processi figli, e quando N di essi hanno fatto quello
che dovevano fare inizia a terminarli.
Mi sorgono alcune domande:
1) Se in un processo "aggancio" un segnale con signal() e poi chiamo pause(),
quando viene spedito quel segnale sembra che prima venga eseguita la funzione
di gestione del segnale, e soltanto dopo il codice che c'e` dopo pause().
Succede sempre cosi`, o il comportamento puo` essere non deterministico?
2) Il gestore di default di SIGUSR2 termina il processo? Se nella parte che
gestisce i processi figli non "aggancio" SIGUSR2, succede proprio questo (e il
codice dopo la pause() non viene mai eseguito).
3) Apparentemente, se spedisco un segnale a un processo e solo in seguito
chiamo la pause() in tale processo, quest'ultima non blocca l'esecuzione (ossia
il segnale resta "in coda" finche` non viene chiamata la pause(), anche se nel
mentre il gestore del segnale era gia` stato chiamato). Cio` che ho detto e`
giusto?
4) Come mai se metto dei valori alti per M (da me basta 1000) va tutto in
crash, incluso il window manager? E senza nemmeno un core dump, semplicemente
ritorno alla schermata di login di xdm. Per pochi istanti si vede una finestra
grigia che contiene un warning e molti punti esclamativi, ma non faccio in
tempo a leggere cosa c'e` scritto. In /var/log/ non c'e` niente di buono.
5) Se invece metto dei valori alti sia per N che per M (ad esempio 500-500),
dopo che 'tot' processi (qui da me attorno ai 400) hanno fatto quello che
dovevano fare e hanno spedito il loro segnale, apparentemente si blocca tutto.
Sembra che ci sia un'ipotetica "coda dei segnali" che va in tilt nel processo
padre, che non riesce piu` a passare il loop della pause(). Cosa succede?
(fra l'altro se blocco il programma con CTRL-C non resta in esecuzione nessun
processo figlio, sebbene non siano stati inviati tutti i segnali necessari.
Devo presupporre che CTRL-C - che se non sbaglio invia un SIGTERM - si
"propaghi" anche in tutti i processi figli?)
Per chiudere gradirei sapere se nel codice sotto riportato, a parte eventuali
errori, ci sono delle "trovate" che sarebbe meglio fare in un altro modo.
Grazie per l'attenzione.
--
Bye! Lorenzo Lutti
http://www.geocities.com/SiliconValley/Peaks/6258/
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
int nVolte=0;
void Segnale1()
{
 printf( "Segnale numero %d inviato da un child\n", nVolte++);
 signal( SIGUSR1, Segnale1);
}
void Segnale2()
{
 printf( "Segnale di fine inviato dal padre al PID %d\n", getpid());
 signal( SIGUSR2, Segnale2);
}
int main( int argc, char *argv[])
{
 int *pids, pid, a, n, m;
 n = atoi( argv[1]);
 m = atoi( argv[2]);
 pids = (int*)malloc( sizeof(int)*m);
 signal( SIGUSR1, Segnale1);
 for( a=0; a<m; a++)
  if( (pid = fork()) != 0)
  {
   /* padre */
   pids[a] = pid;
  }
  else
  {
   /* figlio */
   signal( SIGUSR2, Segnale2);
   printf( "Inizio del figlio con PID=%d\n", getpid());
   kill( getppid(), SIGUSR1);
   pause();
   printf( "Fine del figlio con PID=%d\n", getpid());
   exit( 0);
  }
 /* padre */
 while( nVolte < n)
  pause();
 for( a=0; a<m; a++)
 {
  kill( pids[a], SIGUSR2);
  wait( NULL);
 }
 free( pids);
 printf( "Fine del padre.\n");
 return 0;
}

errori, ci sono delle "trovate" che sarebbe meglio fare in un altro modo.
Usa sigaction invece di signal.
Controlla i valori restituiti da malloc (usa un banale wrapper xmalloc)
e da fork per eventuali errori.
Usa indent -kr sul tuo codice e impara ad usare questo stile.
-- 
ciao, | [Per rispondere togli "toglimi" dal mio indirizzo.]
Marco | * The Internet is full. Go away.  -- Joel Furr *
      | (Ri)scoprire fidonet: 
http://bbs.mi.linux.it

 Usa indent -kr sul tuo codice e impara ad usare questo stile.
OE (come sempre) ha strippato l'indentazione che avevo dato al sorgente. A
parte questo uso lo stesso stile da diversi anni, stile che fra l'altro ho
imparato proprio dal libro sul C di K&R, e quindi non penso che lo cambiero`.


imparato proprio dal libro sul C di K&R, e quindi non penso che lo cambiero`.
Secondo te perche` il parametro si chiama "-kr"? :-)


 Secondo te perche` il parametro si chiama "-kr"? :-)
Appunto! Lo dicevo proprio perche` uso gia` quella convenzione, non ho bisogno
del filtro...
Grazie per le risposte. Inizio ad apprezzare i tuoi messaggi sintetici, perche`
a ragion veduta contengono tutte e sole le verita`... :)
