Pthread

sysunix Messages postés 3 Date d'inscription   Statut Membre Dernière intervention   -  
Dalfab Messages postés 706 Date d'inscription   Statut Membre Dernière intervention   -
Bonjour,

J'utilise un programme des threads coopératifs qui sert à créer 2 threads et affecter chacun d'eux à un core différent en utilisant la routine
pthread_setaffinity_np
et
pthread_getaffinity_np
pour déterminer les paramètres des threads en cours d'exécution; mais cette partie ne fonctionne pas dans de programme.

Voilà le code que j'utilise:

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<sys/syscall.h>
#include<string.h>
#include<unistd.h>
#include<math.h>
#include<time.h>

#define mask1 4
#define mask2 8
#define nbr_threads 2
#define N 10

void *thread_body_function( void *threadid );
void dec2bin( unsigned long decimal, char *binary );
double waste_time( long n );
pid_t gettid( void );
 /* Les variables globales doivent etre déclarées avant main() */

pthread_mutex_t mutextab;

int tab[N];
int k;
main(  )
{
 unsigned long decimal[nbr_threads];
 unsigned long mask_thread[nbr_threads];
 unsigned int lenmask_thread[nbr_threads];
 pthread_attr_t attr;
 clock_t start, end;
 double cpu_time_used;

 char binary[80];

 pthread_t threads[nbr_threads];

 int ret[nbr_threads]; /* contient les resultats de pthread_create */
 int i;
 long t;

 system( "clear" );

 /* determination du nombre de processeur actuel */

 int NUM_PROCS = sysconf( _SC_NPROCESSORS_CONF );
 printf( "\n Le systeme à %i processors. \n", NUM_PROCS );
 printf( "\n L'identificateur du processus main thread est: %d \n", getpid(  ) );

 // int r=10;
 start = clock();

 /* Creation des threads coopératifs sur la fonction thread_body_function */

 t = 0;
 while ( t < nbr_threads )
    {

            ret[t] = pthread_create( &threads[t], NULL, thread_body_function, ( void * )t );
 switch ( t )
 {
  case 0: /* thread # 1 */
   {
    decimal[t] = mask1;
    mask_thread[t] = mask1; /* Les processeurs definis en mask1 ex 3= 0,1 */
    break;
   }
  case 1: /* thread #2 */
   {
    decimal[t] = mask2;
    mask_thread[t] = mask2;
    break;
    }
  default: /* sinon */
    {
    decimal[t] = 1;
    mask_thread[t] = pow( 2, NUM_PROCS )-1;
    }
  }
        lenmask_thread[t] = sizeof( mask_thread[t] );

        if ( ret[t] == 0 )
  {
      /* =======settig Thread scheduling affinity ======== */

          if ( pthread_setaffinity_np ( threads[t], lenmask_thread[t], &mask_thread[t] ) < 0 )

          {  
    perror( "pthread_setaffinity_np" );
   }
   else
   {
    decimal[t] = mask_thread[t];
    dec2bin( decimal[t], binary );
    printf ( "thread %ld affinity utilise pthread_setaffinity_np en binaire : %s en Hex :%08lx  \n",
t, binary, mask_thread[t] );
          }

    /* =======getting thread scheduling affinity ======== */

   if ( pthread_getaffinity_np ( threads[t], lenmask_thread[t], &mask_thread[t] ) < 0 )
   {
    perror( "pthread_getaffinity_np" );
   }
   else
   {
    decimal[t] = mask_thread[t];
           dec2bin( decimal[t], binary );
    printf( "thread %ld affinity using pthread_getaffinity_np en binaire :%s en Hex :%08lx \n \n",
t, binary, mask_thread[t] );
          }
   }
/*============================================================================*/
         else
   {
    printf( "thread %li n'est pas créé \n", t );
   }
    t = t + 1;
  }

  t = 0;
  while ( t < nbr_threads )
   {
    pthread_join( threads[t], NULL );
    t = t + 1;
   }

  end = clock();
  cpu_time_used = ( (double)(end-start) / CLOCKS_PER_SEC );
  printf( "Le temps CPU utilisé par ce programme est: %f\n", cpu_time_used );
  exit(0);
        }

        /*=========Definition de la fonction============*/
        /* Cette fonction renvoie l'identificateur du thread appelé */
        pid_t gettid( void )
        {
  return syscall( __NR_gettid );
        }

        /* la fontion sur laquelle les threads sont créé */
        void *thread_body_function( void *threadid )
        {

  long tid;
  tid = *(long*)threadid;
  int j;
  int i;
  int tab1[N];

  printf( "\n" );
  printf( "le thread # %ld est créé \n", tid );
  printf( "L'identificateur du thread %ld est : %d \n",*(long*)threadid, ( int )gettid() );

  /*  Consomation du temps afin que le fonctionnement des threads soit visible */

  printf( "Le temps consommé par thread %ld est : %f\n", *( long * )threadid,
waste_time(2000) );

  for ( i=0; i<N; i++ )
   {
    tab[i] = 25;
    printf( "tab[%d]=%d le tableau d'init \n", i, tab[i] );
   }

 for ( i=0;i<N;i++ )
   {
    pthread_mutex_lock( &mutextab );
    for (j=0; j<N; j++)
     {
      tab1[j] = tab[i];
      printf( "tab[%d]=%d  thread n %ld  \n", j, tab1[j], tid );
     }
    pthread_mutex_unlock( &mutextab );
    pthread_exit( ( void * )0 );
    }
           }

        double waste_time( long n )
         {
   double res = 0;
   long i = 0;
   while ( i < n * 200000 )
    {
     i++;
     res += sqrt(i);
     res = 10;
    }
    return res;
         }

       /*  conversion from decimal to binary */
       void dec2bin( unsigned long decimal, char *binary )
       {
 int k = 0, n = 0;
 int remain;
 unsigned long old_decimal;
 char temp[80];

 do
 {
         old_decimal = decimal; // for test
  remain = decimal % 2;
         decimal = decimal / 2;
         temp[k++] = remain + '0';
        }

 while ( decimal > 0 ); 
 temp[k++] = ' ';
 /* space */ 

 /* reverse the spelling */

 while ( k >= 0 )
  binary[n++] = temp[--k];
 binary[n - 1] = 0; // end with NULL
      }

1 réponse

Dalfab Messages postés 706 Date d'inscription   Statut Membre Dernière intervention   101
 
Bonjour,
A ma connaissance, pthread_getaffinity_np() reçoit en en paramètre une structure cpu_set_t à remplir et non pas un long.
D'autre part je suis pas sûr que l'affinité puisse être prise en compte simplement (c'est une préférence et dans tous les cas le noyau basculera le thread sur le processeur demandé quand il le pourra)
0
sysunix Messages postés 3 Date d'inscription   Statut Membre Dernière intervention  
 
mais si on la declare de type cpu_set_t elle ne peut pas recevoir une variable de type int comme cette intruction par exemple decimal[t] = mask2.
0
Dalfab Messages postés 706 Date d'inscription   Statut Membre Dernière intervention   101 > sysunix Messages postés 3 Date d'inscription   Statut Membre Dernière intervention  
 
Et donc il ne faut pas faire decimal[t] = mask2
0
sysunix Messages postés 3 Date d'inscription   Statut Membre Dernière intervention  
 
voila ce qu'il m'affiche lors de l'execution:
Le systeme à 8 processors.

L'identificateur du processus main thread est: 4363
thread 0 affinity utilise pthread_setaffinity_np en binaire : 100 en Hex :00000004
thread 0 affinity using pthread_getaffinity_np en binaire : 100 en Hex :00000004

Segmentation fault (core dumped)
0