Aller au menu - Aller au contenu

[Plan du site] Vous êtes ici --- > Le Site du Zéro > Les tutoriels > Non-Officiels > Programmation > C > Les sockets > Les sockets entre deux applications > Les threads et les mutex > Lecture du tutoriel

Les threads et les mutex

Vous vous apprêtez à lire un tutoriel rédigé par un membre de ce site. Malgré tout le soin que ce membre a pu apporter au tutoriel, nous ne pouvons pas garantir que les informations contenues sur cette page sont exactes à 100%. Merci de garder cela en tête lorsque vous lirez cette page ;o)
Avatar
Auteur : zephyr111
Note : 19 / 20 (10 votes)
Visualisations : 13 143

Plus d'informations Plus d'informations
Dans ce chapitre, nous allons parler des threads, des processus et des mutex. Il est relativement important car il constitue la partie théorique du cours sur les threads et permet d'installer une bibliothèque nommée Pthread ;) .
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire

Quelques définitions

Les processus



Un processus est une tâche qui est en train de s'exécuter.
Par exemple, quand vous lancez un de vos programmes que vous avez développé, votre OS crée un nouveau processus et celui-ci exécutera une suite d?instructions sur votre ordinateur (le code de votre programme compilé).

Citation : Wikipédia
Un processus est défini par :
  • Un ensemble d'instructions à exécuter
  • Un espace mémoire pour les données de travail
  • Éventuellement, d'autres ressources, comme des descripteurs de fichiers, des ports réseaux, etc...

Si vous être sous Windows, vous pouvez accéder à la liste des processus via un gestionnaire des tâches (en appuyant simultanément sur les touches CTRL+ALT+SUPPR).
Sous linux, vous pouvez accéder à la liste des processus via un indicateur de performance.
Plus d'informations : ici.


Les threads



Un même processus peut se décomposer en plusieurs parties, qui vont s'exécuter simultanément en partageant les mêmes données en mémoire. Ces parties se nomment threads.
Du point de vue de l'utilisateur, les threads semblent se dérouler en parallèle.
Lorsqu'une fonction bloque par exemple un programme (comme la fonction recv()), si celui-ci dispose d'une interface graphique, il sera inactif tant que la fonction le bloquera. Les threads nous permettrons de régler ce problème.
Plus d'informations : ici.


Les mutex



Il est parfois nécessaire d'interdire momentanément certaines opérations d'un ou plusieurs threads : par exemple, si plusieurs threads sont amenés à lire une variable, faire des calculs avec puis la modifier en fonction du résultat de ces calculs, il ne faut pas qu'ils le fassent en même temps, sinon cela risque tous simplement de bugger.
Les mutex permettent donc d'éviter ces problèmes de synchronisation :) .
Plus d'informations : ici.


Pourquoi choisir la bibliothèque pthread ?



Le terme Pthread est une abréviation de "POSIX Threads".
POSIX est lui un acronyme de "Portable Operating System Interface for UniX".

J'ai donc choisi pthread car c'est une très bonne bibliothèque portable permettant de manipuler les threads, les processus et les mutex assez facilement ;) .

Installation de pthread

Sous Windows



Sous Windows, cette bibliothèque n'est pas installée par défaut, il va donc falloir le faire.
Nous allons dans un premier temps télécharger la bibliothèque puis l'installer et ensuite nous pourrons l'utiliser dans nos programmes.


Vous pouvez obtenir la bibliothèque pthread en cliquant sur le lien qui suit :
Pthread - Win32 - Version 2.8.0

Commencez par ouvrir l'exécutable et cliquez sur le bouton "Extract".
Ainsi, trois dossiers sont créés dans le même répertoire de l'exécutable.
Le dossier "pthreads.2" contient les sources de la bibliothèque. Elles vous seront utiles dans le cas où vous devriez compiler vous même la bibliothèque.
Le dossier "Pre-built.2" contient les fichiers .h à inclure et les fichiers .lib à linker.
C'est donc ce dossier qui va nous intéresser, ouvrez le ;) .

Mettez les fichiers .lib/.a dans le dossier "lib" de votre compilateur et les headers (les fichiers .h) dans le dossier "include".

Petit rappel :
Pour ceux qui utilisent VC, prenez les fichiers ayant les extensions .lib.
Pour ceux qui utilisent Code::Blocks ou Dev-C++, prenez les fichiers ayant l?extension .a.

Une fois la bibliothèque pthread installée, nous allons linker les fichiers .lib/.a à notre projet et inclure les headers dans notre code. En fonction de votre IDE et du langage que vous avez choisi d'utiliser, le fichier linké ne sera pas le même :
Si vous faîtes du C, linkez le fichier "pthreadVC2.lib" pour VC et le fichier "libpthreadGCc.a" pour Code::Blocks et Dev-C++.
Sinon si vous faîtes du C++, linkez le fichier "pthreadVCE2.lib" pour VC et le fichier "libpthreadGCEc.a" pour Code::Blocks et Dev-C++.

Il en est de même pour les DLL ;) :
Si vous faîtes du C, prenez la DLL "pthreadVC2.dll" pour VC et la DLL "pthreadGC2.dll" pour Code::Blocks et Dev-C++.
Sinon si vous faîtes du C++, prenez la DLL "pthreadVCE2.dll" pour VC et la DLL "pthreadGCE2.dll" pour Code::Blocks et Dev-C++.
La DLL doit être mise dans le répertoire de votre projet.

Note : Vous pouvez mettre la DLL dans le répertoire "X:\WINDOWS\system32\" (ou X est le nom du disque dur contenant le dossier Windows). Ainsi, la DLL n'a plus besoin d'être dans le répertoire de vos projets :) sur votre ordinateur.

Nous allons ensuite inclure pthread comme ceci :

Code : C
1
#include <pthread.h>



Sous Linux



Sous linux la bibliothèque est déjà installée normalement, vous n'aurez donc pas besoin de le faire :) .
Toutefois sachez que les sources utilisant les threads nécessitent une édition de lien avec la librairie pthread :

Code : Console
gcc nomSource.c -lpthread -o nomExecutable


Les threads

Dans cette partie nous allons voir comment utiliser les threads avec la bibliothèque pthread.

Déclarer un thread



Pour pouvoir utiliser notre thread, nous allons déclarer une variable de type pthread_t.

Le type pthread_t est en fait un entier qui représente l'ID du thread utilisé. Cet ID permet au programme d'effectuer des opérations sur un thread. Nous ne manipulerons jamais cette ID directement, mais toujours par l'intermédiaire d'une variable ;) .

Code : C
1
pthread_t thread;

Créer un thread



La fonction pthread_create va nous permettre de créer un thread et d'exécuter une fonction en parallèle. Voici son implémentation:

Code : C
1
int pthread_create(pthread_t* thread, pthread_attr_t_* attr, void*(*start_routine)(void*), void* arg);
Toutefois, pour éviter des erreurs de compilation, la fonction exécutée par le thread créé devra avoir le prototype suivant :

Code : C
1
void* fonction(void* data);

Dans l'exemple qui suit, le thread thread va exécuter la fonction ma_fonction avec comme paramètre l'entier valeur.

Code : C
1
pthread_create (&thread, NULL, ma_fonction, (void*)&valeur);

Pour le dernier argument, &valeur sera un int*, mais pour le transformer en void* nous ferons un cast :) .

Attendre la fin de l'exécution d'un thread



La fonction pthread_join va permettre d'attendre la fin du thread c'est à dire la fin de l'exécution de la fonction exécutée par celui-ci. Voici le prototype:

Code : C
1
int pthread_join(pthread_t th, void **thread_return);

Terminer un thread



Dans certain cas, il est possible que la fonction principale d'un thread ne se termine jamais, notamment lorsque l'on utilise une boucle infinie. Dans ce cas, on doit forcer la fin de du thread avec la fonction pthread_exit :

Code : C
1
void pthread_exit(void *retval);

Un petit exemple :



Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// On inclue les fichiers standard et le header pthread.h
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
 
void* maFonction(void*);
 
 
 
int main()
{
    pthread_t thread;// On crée un thread
    pthread_create (&thread, NULL, maFonction, NULL);// Permet d'exécuter le fonction maFonction en parallèle
 
    // Affiche 50 fois 1
    for(int i=0 ; i<50 ; i++)
        printf("1");
 
    // Attend la fin tu thread créé
    pthread_join(thread, NULL);
    return 0;
}
 
 
void* maFonction(void*)
{
    // Affiche 50 fois 2
    for(int i=0 ; i<50 ; i++)
        printf("2");
}

Le résultat donné est le suivant :

Code : Console
1111111111222222222222222222222222222222222111111111111111111111111111111111112222222222222222211111

Comme vous pouvez le voir, l'utilisation des threads permet d?exécuter une fonction en parallèle.

Mais pourquoi les nombres s'affichent par paquets ? Si les fonctions se lançaient en parallèle, je devrais obtenir 12121212...

Si les nombres s'affichent par paquet, c'est à cause de votre OS.
En effet, la fonction principale (main) et la fonction exécuté par le thread créé (maFonction) ne se lance pas tout à fait en parallèle car votre OS va attribuer un temps d'exécution pour chaque thread.
Votre OS va, par exemple, exécuter le code du thread n°1 de votre processus pendant 8 ms, puis va exécuter le code du thread n°2 du même processus aussi pendant 8 ms, etc. ...
Il en est de même pour le fonctionnement des processus ;) .
Ainsi, comme chaque thread est exécuté à tour de rôle pendant un temps très court, vous avez l'impression qu'ils se déroulent en parallèle ^^.

Chapitre précédent Sommaire
Retour en haut Retour en haut


Créé : le 03/03/2007 à 15:49:16
Modifié : le 22/08/2008 à 15:50:48
Avancement : 100%
Licence : Copie non autorisée

12 commentaires

Changer de design | En savoir plus | Plan du site | Politique d'accessibilité | Règles | RSS tutoriels | RSS news
Édité par Simple IT SARL : Nous contacter | Notre blog | Revue de presse | Publicité

Y'a plus rien à lire, faut remonter maintenant !

Hébergement web - Correction de tutoriels - Créer un site
Vous souhaitez apparaître ici ? Contactez-nous.

Nombre de connectés 97 Zéros connectés | Requêtes SQL 8 requêtes | Temps de génération de la page : Total (SQL) 0.076s (0.0646s)