Page 1 of 1

Cours sur le thread pool en win32

Posted: Mon Jan 26, 2026 4:12 pm
by Hydraxx
# Le Thread Pool Win32

Salut aujourd’hui on va voir **un composant fondamental de Windows moderne** :
**le Thread Pool Win32**. 8-)

Le Thread Pool est partout :

* services Windows
* réseau
* I/O asynchrone
* timers
* tâches système
* composants internes de l’OS

Beaucoup de développeurs utilisent encore `CreateThread` sans comprendre **comment Windows gère réellement les threads**.
Ici on va voir **ce qu’est le Thread Pool**, comment il fonctionne, et comment l’utiliser **proprement en Win32**.

---

# 1) C’est quoi le Thread Pool Win32

Le **Thread Pool Win32** est un **mécanisme de gestion de threads géré par Windows**.

Au lieu de créer un thread à chaque tâche, Windows :

* crée un nombre optimal de threads
* les réutilise
* les planifie intelligemment
* évite la surcharge CPU

Le développeur **ne contrôle plus les threads**, mais **les tâches**.

---

# 2) Pourquoi CreateThread est une mauvaise idée

Créer un thread manuellement :

* coûte cher
* ne scale pas
* surcharge le scheduler
* provoque trop de context switch
* peut planter une application sous charge

`CreateThread` est :

* ancien
* bas niveau
* non scalable

Le Thread Pool est :

* moderne
* plus rapide
* plus sûr
* recommandé par Microsoft

---

# 3) Principe général du Thread Pool

Le fonctionnement est toujours le même :

1. Définir un callback
2. Créer un objet Thread Pool
3. Soumettre la tâche
4. Windows exécute le callback sur un thread du pool

Le développeur ne sait pas :

* quel thread sera utilisé
* quand exactement

---

# 4) Les 4 objets du Thread Pool

Le Thread Pool Win32 repose sur **4 types d’objets** :

* Work → tâche ponctuelle
* Timer → tâche différée ou périodique
* Wait → attente sur un HANDLE
* I/O → I/O asynchrone

---

# 5) Callback : le cœur du Thread Pool

Tout passe par un **callback**.

Un callback :

* est exécuté par Windows
* tourne dans un thread du pool
* doit être rapide
* ne doit pas bloquer longtemps

---

# 6) WORK — exécution d’une tâche simple

Le Work est le plus utilisé.

Il sert pour :

* calcul
* traitement mémoire
* compression
* chiffrement
* envoi réseau

---

## Callback Work

Code: Select all

VOID CALLBACK WorkCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Context,
PTP_WORK Work
)
{
int value = *(int*)Context;
printf("Work exécuté : %d\n", value);
}
---

## Création et soumission d’un Work

Code: Select all

int main()
{
int data = 42;

```
PTP_WORK work = CreateThreadpoolWork(
    WorkCallback,
    &data,
    NULL
);

SubmitThreadpoolWork(work);

Sleep(1000);

CloseThreadpoolWork(work);
```

}
---

# 7) TIMER — exécution différée ou périodique

Le Timer permet d’exécuter du code après un délai ou de manière périodique.

---

## Callback Timer

Code: Select all

VOID CALLBACK TimerCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Context,
PTP_TIMER Timer
)
{
printf("Timer déclenché\n");
}
---

## Création et armement du Timer

Code: Select all

int main()
{
PTP_TIMER timer = CreateThreadpoolTimer(
TimerCallback,
NULL,
NULL
);

```
FILETIME ft;
ULONGLONG delay = (ULONGLONG)-50000000;

ft.dwLowDateTime  = (DWORD)delay;
ft.dwHighDateTime = (DWORD)(delay >> 32);

SetThreadpoolTimer(timer, &ft, 0, 0);

Sleep(7000);

CloseThreadpoolTimer(timer);
```

}
---

# 8) WAIT — attente sur un HANDLE

Le Wait permet d’exécuter un callback lorsqu’un objet noyau est signalé.

---

## Callback Wait

Code: Select all

VOID CALLBACK WaitCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Context,
PTP_WAIT Wait,
TP_WAIT_RESULT Result
)
{
printf("Objet signalé\n");
}
---

## Exemple avec Event

Code: Select all

int main()
{
HANDLE hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

```
PTP_WAIT wait = CreateThreadpoolWait(
    WaitCallback,
    NULL,
    NULL
);

SetThreadpoolWait(wait, hEvent, NULL);

Sleep(2000);
SetEvent(hEvent);

Sleep(1000);

CloseThreadpoolWait(wait);
CloseHandle(hEvent);
```

}
---

# 9) I/O — Thread Pool et I/O asynchrone

Le Thread Pool I/O permet de gérer les opérations d’entrée sortie sans bloquer de thread.

---

## Callback I/O

Code: Select all

VOID CALLBACK IoCallback(
PTP_CALLBACK_INSTANCE Instance,
PVOID Context,
PVOID Overlapped,
ULONG IoResult,
ULONG_PTR BytesTransferred,
PTP_IO Io
)
{
printf("I/O terminé : %llu bytes\n", BytesTransferred);
}
---

## Création du Thread Pool I/O

Code: Select all

HANDLE file = CreateFileW(
L"test.txt",
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);

PTP_IO io = CreateThreadpoolIo(
file,
IoCallback,
NULL,
NULL
);
---

# 10) Synchronisation dans les callbacks

À utiliser :

* InterlockedIncrement
* InterlockedExchange
* CRITICAL_SECTION
* SRWLOCK

À éviter :

* Sleep
* attente bloquante longue
* deadlocks

---

# 11) Fermeture correcte

Chaque objet Thread Pool doit être fermé explicitement.

Sinon des fuites de ressources apparaissent.

---

# À retenir

Le Thread Pool est géré par Windows.
On ne gère plus des threads mais des tâches.
C’est le modèle moderne recommandé en Win32.
Comprendre le Thread Pool, c’est comprendre comment Windows exécute le code en parallèle.