/* Petit programme pour illustrer le passage d'un unique argument a un
   thread et le retour d'un unique resultat simple.

   Le progromme cree nbThreads threads, ou chacun imprime simplement
   son numero de threads et retourne une valeur en relation avec son
   numero de threads.
    
   gcc ceFichier.c -lpthread
   a.out nbThreads
*/
 
#include <pthread.h>
#include <stdio.h>
#include <assert.h>

/* En-tete de la fonction pour les threads qui seront crees. */
void *proc( void *arg );

/* Nombre maximum de processsus qui seront crees. */
#define MAX_NB_THREADS 100

int main( int argc, char *argv[] ) 
{
  pthread_t procIds[MAX_NB_THREADS];  
  pthread_attr_t attr;

  int i, res;
  int nbThreads;   /* Nombre de threads: argument du programme. */

  /* Lecture des arguments a utiliser pour l'appel. */
  assert( argc >= 2 );
  nbThreads = atoi(argv[1]);
  assert( nbThreads > 0 && nbThreads <= MAX_NB_THREADS );

  /* Initialisation (standard) de la structure d'attribut pour le thread. */
  pthread_attr_init(&attr);
  pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );

  /* Creation des threads. */
  for ( i = 0; i < nbThreads; i++ ) {
    /* On passe l'unique argument entier par l'intermediaire d'un cast. */
    pthread_create( &procIds[i], &attr, proc, (void *) i );
  }

  /* Attente que les threads se terminent. */
  for ( i = 0; i < nbThreads; i++ ) {
    pthread_join( procIds[i], (void *) &res );
    printf( "Execution d'un join avec le threads #%d => %d\n", i, res );
  }
  printf( "-- Fin du programme --\n" );
}

void *proc( void *arg ) 
{
  int numId = (int) arg;
  printf( "Le thread #%d s'execute\n", numId );
  pthread_exit( (void*) (100*numId+1) ); /* Retour d'un resultat. */
}
