0% ont trouvé ce document utile (0 vote)
28 vues5 pages

Introduction aux threads POSIX

Le document décrit la notion de threads en utilisant la librairie POSIX pthreads. Il présente différents exemples de programmes utilisant des threads pour afficher des caractères, incrémenter des variables partagées et créer un grand nombre de threads.

Transféré par

DKT Group
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
28 vues5 pages

Introduction aux threads POSIX

Le document décrit la notion de threads en utilisant la librairie POSIX pthreads. Il présente différents exemples de programmes utilisant des threads pour afficher des caractères, incrémenter des variables partagées et créer un grand nombre de threads.

Transféré par

DKT Group
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Notion de threads

1 Introduction
Nous allons aborder les threads dans leur standard PoSiX. Il existe bien d’autres librairies de
threads mais celle-ci a l’avantage de représenter une norme internationale soutenue par nombre d’uni-
versités et d’entreprises.

1.1 Utiliser la librairie [Link]


Pour utiliser cette librairie il faut indiquer dans la ligne de commande de compilation la directive
-lpthread. Celle-ci indique tout simplement que vous incluez la librairie [Link].
Par exemple pour compiler le fichier permut.c qui contient des instructions pthreads en un fichier
objet permut.o vous devez écrire gcc -c -lpthread permut.c

2 Deux threads d’affichage


Le programme suivant crée 2 threads qui vont afficher 1000 fois le caractère ’a’ et ’b’ respective-
ment.

#include <stdio.h>
#include <pthread.h>

void * process(void * arg){ // Un seul argument de type void *


int i;
fprintf(stderr, "Starting process %s\n", (char *) arg);
for (i = 0; i < 10000; i++) { // Ecrit sur la sortie standard
write(1, (char *) arg, 1);
}
return NULL;
}

int main(void){
int retcode;
pthread_t th_a, th_b;
void * retval;

// création de la thread th_a


retcode = pthread_create(&th_a, NULL, process, (void *) "a");
if (retcode != 0) fprintf(stderr, "create th_a failed %d\n", retcode), exit(1);

// création de la thread th_b


retcode = pthread_create(&th_b, NULL, process, (void *) "b");
if (retcode != 0) fprintf(stderr, "create th_b failed %d\n", retcode), exit(1);

1
// attente de la terminaison de la thread th_a
retcode = pthread_join(th_a, &retval);
if (retcode != 0) fprintf(stderr, "join a failed %d\n", retcode), exit(1);

// attente de la terminaison de la thread th_b


retcode = pthread_join(th_b, &retval);
if (retcode != 0) fprintf(stderr, "join b failed %d\n", retcode), exit(1);

return 0;
}

Le programme principal crée avec la commande pthread create( &th a, NULL, process, (void
*) ’a’ ) la thread th a et lui associe la fonction process qui prend en argument le caractère ’a’. Si
la création a pu se faire la valeur retournée par ptread create est 0. Ensuite le programme principal
attent la terminaison de la thread th a avec l’instruction pthread joint( &th a, ret val ) qui
retourne également la valeur 0 si tout c’est bien passée.
Il fait de même avec la thread th b et le caractère ’b’.

3 Trois threads d’incrémentation


Le programme crée un tabelau de 3 threads qui incrémentent un tableau de 3 entiers. Cette variable
est globale aux 3 threads. L’indice des threads dans le tableau des threads permet à chaque thread de
savoir quel élément du tabelau elle doit incrémenter.
Ici les threads sont tuées brusquement avec la fin du processus !

#include <pthread.h>
#include <stdio.h>
#include "outils.h"

int val[3] ; // tabelau en global de 3 entiers

// déclaration de la fonction associée aux threads


void * thread (void *) ;

int main (int c, char *v[]) {


int num, i ;

// tabelau des 3 threads


pthread_t pthread_id[3] ;

// structure regroupant les attributs des threads


pthread_attr_t pthread_attr ;
int res ;

// récupération des attributs des threads


pthread_attr_init( &pthread_attr ) ;

// choix du RR comme répartiteur


pthread_attr_setschedpolicy( &pthread_attr, SCHED_RR ) ;

2
// creation de 3 threads qui executent toute la fct thread
// mais avec le numero de la thread en parametre!!!
for( num=0 ; num<3 ; num++ )
{
res = pthread_create( pthread_id+num, &pthread_attr,
thread, ( void * ) num ) ;

if( res != 0 ) syserr( "thread_create" ) ;


}

for( i=0 ; i<3000 ; i++ )


// affiche la valeur pour chacune des threads
printf( "%d %d %d\n", val[0], val[1], val[2] ) ;

exit( 0 ) ;
}

void * thread (void *num) {


for( ; ; ) // incrementation de la valeur associée à cette thread
val[(int)num]++ ;
}

4 Toujours plus !
Le programme principal peut aussi créer 2000 threads et attendre leurs fins avant de terminer
lui-même.

#include <errno.h>
#include <stdio.h>
#include <pthread.h>

void * test_thread (void *cpt) {


unsigned int count = (unsigned int) *cpt ;

fprintf( stdout, "le compteur vaut %d\n", count ) ;


sleep( 5 ) ; // une pause

return NULL;
}

int main (void) {


unsigned long count;

setvbuf (stdout, NULL, _IONBF, 0);


// Mettre le buffer à vide pour écrire sans tampon

for (count = 0; count < 2000; ++count) {


pthread_t thread;
int status;

3
status = pthread_create (&thread, NULL, test_thread, ( void * ) &count );

if (status != 0) {
fprintf ( stderr,
"status = %d, count = %lu: %s\n",
status, count,strerror (errno));
exit( 1 );
}
else {
printf ("count = %lu\n", count);
}

pthread_join (thread, NULL); // Attente de la thread


usleep (10); // une pause
}

return 0;
}

5 Exercices
1. À l’aide de threads, proposez un module de multication matricielle.
2. Toujours à l’aide de threads, proposez un module de lissage d’une image par le masque suivant :
1/9 1/9 1/9
1/9 1/9 1/9
1/9 1/9 1/9
Le résultat sera stoché dans uen nouvelle image. Appliquer ce masque à une image revient à
sur-imposer ce masque à l’image, à multiplier les pixels surimposés par les valeurs du masque,
en faire la somme et changer la valeur du pixel central (par rapport au masque) par le résultat
de la somme.
Une image test vous sera fournie pour laquelle vous devrez faire un thread permettant la lecture
de son fichier. Son format commence par 3 lignes de commentaires suivies de la matrice de
caractères contenant l’image. La deuxième ligne indique la dimension en lignes, colonnes de
l’image. La troisième ligne indique la valeur maximale du niveau de gris.
3. Écrivez le filtrage médian d’une image !
Voici la fonction de lecture d’une image que vous aurez besoin avant toute chose. vous pouvez créer
une thread de lecture ! L’image qui sera alors stockée dans le tabelau in image de taille dimx × dimy
et de type char.

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// taille d’une image 512x512...


#define STDSIZE 262144
#define STDDIMX 512
#define STDDIMY 512

4
#define HALFSTDDIMX 255
#define HALFSTDDIMY 255

main (int argc, char *argv[]) {


FILE *f;
char comment[BUFSIZ];
char picture_type[2];
char in_file_name[20];
char *in_image;
int dimx, dimy, nvg, in_image_size;

// ouverture du fichier image en mode lecture...


if ((f=fopen(argv[1],"r"))==NULL)
fprintf (stderr,"Erreur a l’ouverture du fichier : %s\n", argv[1]), exit (-1);

// verifier que c’est une image PGM... ignorer l’entete


fscanf (f,"%s\n",picture_type);
if (strcmp(picture_type,"P5"))
fprintf (stderr,"Erreur : ce n’est pas un fichier pgm\n"), exit (-1);
fgets (comment,BUFSIZ,f); // lecture du commentaire xv...

// lecture des dimensions...


fscanf (f,"%d %d\n",&dimx,&dimy);

// lecture du nbre de niveau de gris...


fscanf (f,"%d\n",&nvg);

/* reservation memoire et lecture de l’image */


in_image_size = dimx*dimy;
in_image = (char *) calloc (in_image_size,sizeof(char));
fread (in_image,sizeof(char),in_image_size,f);
fclose (f);
}

Vous aimerez peut-être aussi