Cours sur les threads en Win32
Posted: Sun Jan 18, 2026 6:41 pm
Salut,
si tu lis ce tutoriel c’est que tu veux comprendre les threads en Win32.
Pas juste les utiliser, mais savoir ce que c’est réellement et comment Windows exécute ton code.
Ici on va poser les bases, puis passer directement à la pratique avec CreateThread.
Simple, clair, sans détour.
---
Avant tout, il faut comprendre un point fondamental :
il y a les processus et les threads.
Un processus est un conteneur.
Il contient de la mémoire, des ressources, des handles, un contexte de sécurité.
Mais tout seul, un processus ne fait rien.
Il est inerte.
Ce sont les threads qui exécutent réellement le code.
Jamais le processus directement.
Même si dans ton code tu n’as créé aucun thread, ton programme en a quand même un.
C’est normal : chaque processus possède au minimum un thread principal.
C’est ce thread qui exécute ton main() ou ton WinMain().
En résumé :
* le processus contient
* le thread exécute
---
Concrètement, un thread c’est :
* un flux d’exécution
* un bout de code qui s’exécute dans ton processus
Un même processus peut avoir :
* un seul thread
* ou plusieurs threads en même temps
Tous ces threads partagent la mémoire du processus.
---
Comment tout peut s’exécuter “en même temps” ?
Sur un processeur monocœur, un seul thread s’exécute à la fois.
Windows change de thread très rapidement, ce qui donne l’illusion du parallélisme.
Sur un processeur multicœurs, plusieurs threads peuvent réellement s’exécuter en parallèle.
C’est le scheduler de Windows qui décide quand chaque thread s’exécute.
---
Tous les threads d’un même processus partagent :
* la mémoire
* les variables globales
* le heap
C’est puissant, mais dangereux.
Si plusieurs threads accèdent à la même ressource sans protection, tu peux avoir :
* des bugs aléatoires
* des crashs
* des comportements incohérents
C’est pour ça qu’on utilise la synchronisation, pour protéger les ressources partagées.
---
Maintenant, on passe à la création d’un thread.
La fonction de base en Win32 est CreateThread.
Sa signature est la suivante :
Ce qu’il faut retenir :
* tu fournis une fonction
* Windows crée un thread
* ce thread exécute cette fonction en parallèle
La fonction du thread doit respecter ce prototype :
---
Regardons d’abord un exemple sans thread.
Ici :
* tout s’exécute dans le thread principal
* la boucle bloque le programme
* impossible de faire autre chose en parallèle
Si tu ajoutes du réseau, de l’I/O ou une interface, tout sera bloqué.
---
Maintenant, le même exemple avec un thread.
Résultat :
* deux threads
* deux boucles
* les deux s’exécutent en parallèle
Le programme n’est plus bloqué sur une seule tâche.
---
Pourquoi le premier code pose problème ?
Sans thread :
* une boucle infinie bloque tout
* le programme devient non réactif
Avec un thread :
* le travail long est délégué
* le thread principal reste libre
* la structure du programme est plus saine
---
Point très important en C++.
CreateThread n’initialise pas le runtime C/C++.
Si tu utilises :
* malloc / free
* new / delete
* iostream
* le TLS du runtime
Tu peux avoir :
* des fuites
* des crashs aléatoires
* des comportements imprévisibles
C’est pour ça qu’en C/C++ on utilise souvent _beginthreadex.
On verra ça dans le prochain cours.
---
Erreur classique de débutant : créer trop de threads.
Créer un thread pour tout :
* complexifie le code
* dégrade les performances
* rend les bugs difficiles à déboguer
Un bon code :
* utilise peu de threads
* avec un rôle clair
* et une synchronisation maîtrisée
---
À retenir :
Le processus est le conteneur.
Le thread est l’unité d’exécution.
Windows planifie des threads, pas des processus.
CreateThread crée un thread Win32 brut.
En C++, CreateThread a des pièges.
Dans le prochain cours, on verra :
* CreateThread vs _beginthreadex
* pourquoi CreateThread peut poser problème en C++
* et comment créer des threads proprement.
si tu lis ce tutoriel c’est que tu veux comprendre les threads en Win32.
Pas juste les utiliser, mais savoir ce que c’est réellement et comment Windows exécute ton code.
Ici on va poser les bases, puis passer directement à la pratique avec CreateThread.
Simple, clair, sans détour.
---
Avant tout, il faut comprendre un point fondamental :
il y a les processus et les threads.
Un processus est un conteneur.
Il contient de la mémoire, des ressources, des handles, un contexte de sécurité.
Mais tout seul, un processus ne fait rien.
Il est inerte.
Ce sont les threads qui exécutent réellement le code.
Jamais le processus directement.
Même si dans ton code tu n’as créé aucun thread, ton programme en a quand même un.
C’est normal : chaque processus possède au minimum un thread principal.
C’est ce thread qui exécute ton main() ou ton WinMain().
En résumé :
* le processus contient
* le thread exécute
---
Concrètement, un thread c’est :
* un flux d’exécution
* un bout de code qui s’exécute dans ton processus
Un même processus peut avoir :
* un seul thread
* ou plusieurs threads en même temps
Tous ces threads partagent la mémoire du processus.
---
Comment tout peut s’exécuter “en même temps” ?
Sur un processeur monocœur, un seul thread s’exécute à la fois.
Windows change de thread très rapidement, ce qui donne l’illusion du parallélisme.
Sur un processeur multicœurs, plusieurs threads peuvent réellement s’exécuter en parallèle.
C’est le scheduler de Windows qui décide quand chaque thread s’exécute.
---
Tous les threads d’un même processus partagent :
* la mémoire
* les variables globales
* le heap
C’est puissant, mais dangereux.
Si plusieurs threads accèdent à la même ressource sans protection, tu peux avoir :
* des bugs aléatoires
* des crashs
* des comportements incohérents
C’est pour ça qu’on utilise la synchronisation, pour protéger les ressources partagées.
---
Maintenant, on passe à la création d’un thread.
La fonction de base en Win32 est CreateThread.
Sa signature est la suivante :
Code: Select all
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
SIZE_T dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId
);
* tu fournis une fonction
* Windows crée un thread
* ce thread exécute cette fonction en parallèle
La fonction du thread doit respecter ce prototype :
Code: Select all
DWORD WINAPI ThreadFunc(LPVOID param);
Regardons d’abord un exemple sans thread.
Code: Select all
#include <Windows.h>
#include <iostream>
int main()
{
while (true)
{
std::cout << "Boucle principale..." << std::endl;
Sleep(1000);
}
```
return 0;
```
}
* tout s’exécute dans le thread principal
* la boucle bloque le programme
* impossible de faire autre chose en parallèle
Si tu ajoutes du réseau, de l’I/O ou une interface, tout sera bloqué.
---
Maintenant, le même exemple avec un thread.
Code: Select all
#include <Windows.h>
#include <iostream>
DWORD WINAPI ThreadFunc(LPVOID param)
{
while (true)
{
std::cout << "Thread secondaire..." << std::endl;
Sleep(1000);
}
```
return 0;
```
}
int main()
{
HANDLE hThread = CreateThread(
NULL,
0,
ThreadFunc,
NULL,
0,
NULL
);
```
while (true)
{
std::cout << "Thread principal..." << std::endl;
Sleep(1000);
}
return 0;
```
}
* deux threads
* deux boucles
* les deux s’exécutent en parallèle
Le programme n’est plus bloqué sur une seule tâche.
---
Pourquoi le premier code pose problème ?
Sans thread :
* une boucle infinie bloque tout
* le programme devient non réactif
Avec un thread :
* le travail long est délégué
* le thread principal reste libre
* la structure du programme est plus saine
---
Point très important en C++.
CreateThread n’initialise pas le runtime C/C++.
Si tu utilises :
* malloc / free
* new / delete
* iostream
* le TLS du runtime
Tu peux avoir :
* des fuites
* des crashs aléatoires
* des comportements imprévisibles
C’est pour ça qu’en C/C++ on utilise souvent _beginthreadex.
On verra ça dans le prochain cours.
---
Erreur classique de débutant : créer trop de threads.
Créer un thread pour tout :
* complexifie le code
* dégrade les performances
* rend les bugs difficiles à déboguer
Un bon code :
* utilise peu de threads
* avec un rôle clair
* et une synchronisation maîtrisée
---
À retenir :
Le processus est le conteneur.
Le thread est l’unité d’exécution.
Windows planifie des threads, pas des processus.
CreateThread crée un thread Win32 brut.
En C++, CreateThread a des pièges.
Dans le prochain cours, on verra :
* CreateThread vs _beginthreadex
* pourquoi CreateThread peut poser problème en C++
* et comment créer des threads proprement.