Les processus légers (threads) avec std::thread (C++11)

Intro :

Les threads sont utilisés dans ce qu’on nomme  « la programmation concurrente », qui consiste en l’exécution des processus légers. Cela représente une séquence d’exécution du code d’un programme au sein d’un processus. Quelque part, les threads sont des processus légers qui sont exécutés « à l’intérieur » d’un processus.

Les threads d’un même processus partagent la même mémoire et leurs variables. La pile de chaque thread est cependant unique pour chacun d’entre-eux.

Un processus habituel possède un seul thread et ce dernier correspond tout simplement au processus lui-même.

Soit c’est le noyau du système d’exploitation qui s’occupe des threads, soit ils sont gérés dans l’espace utilisateur à travers un gestionnaire spécial !

Prérequis :

– Savoir lire du C++

Explications :

Exemple d’utilisation d’un std::thread :

#include <iostream>
#include <thread>

void f()
{
    std::cout << "Un thread C++11" << std::endl;
}

int main()
{
    std::thread t(f);

    t.join();

    return 0;
}

 

La méthode .join() permet d’assurer que le thread se termine avant de quitter le programme ou la portée du code. Cet appel est bloquant !

Un thread est dans l’état « joignable » s’il est est créé avec une tâche à réaliser.

Le type std::thread (C++11) a une méthode get_id() afin d’obtenir l’id du thread en question.

Il peut exister un problème de synchronisation entre deux threads ! On doit protéger l’accès à certaines ressources si deux threads distincts sont en train d’y accéder en écriture.

Un thread peut être aussi détaché :

#include <iostream>
#include <thread>

void f()
{
    std::cout<< "Un thread C++11" << std::endl;
}

int main()
{
    std::thread t(f);
    t.join();
    t.detach();

    return 0;
}

Qu’est-ce qu’un sémaphore ?

Il permet de synchroniser l’accès à une ressource partagée. Cette ressource peut aussi bien être un bout de code !

Les threads accèdent aux ressources par le biais de ce sémaphore.

Pendant que le thread exécute cette ressource partagée aucun autre thread ne peut y accéder. Dès qu’il a terminé son travail, il libère le sémaphore (qui est nommé aussi « moniteur »).


Qu’est-ce qu’un mutex ?

Le mot « mutex » provient de l’abréviation « Mutual Exclusion ». Il assure que les données partagées sont « mutuellement exclusives ». Il s’agit juste d’une variable qui peut être soit dans l’état « verrouillé » ou soit dans l’état « déverrouillé » !

Pour verrouiller un mutex on utilise la méthode lock().

Dès qu’un thread a fini de travailler avec une donnée / ressource partagée il doit libérer le mutex ! Il faut utiliser la méthode unlock().

On peut déclarer le mutex en même temps que la variable à protéger !

struct Data
{
    int var;
    std::mutex mutex;
};

 

Qu’est-ce qu’une condition ?

Une condition est nécessaire d’être utilisée si l’on veut qu’un thread patiente à l’événement d’un autre thread.

Lorsqu’un thread est en attente d’une condition, il reste bloqué jusqu’à ce que la condition soit réaliser par un autre thread.

Résumé :

Nous avons présenter l’utilisation des thread (processus léger) afin de répartir l’exécution des bouts de code d’un jeu-vidéo.

En effet, les programmes utilisant des threads sur des architectures de type multi-processeurs sont plus rapides que les programmes plus classiques !

Références :

– http://www.iro.umontreal.ca/~dift1169/cours/ift1169/communs/Cours/2P/C12_1169_2P.pdf

– https://fr.wikipedia.org/wiki/Thread_(informatique)

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *