Aller au contenu principal

Synchronisation des Processus et Threads

Introduction​

Quand plusieurs threads ou processus accedent a des ressources partagees, il faut coordonner leurs acces pour eviter les problemes de concurrence.

Problemes de Concurrence​

Race Condition (Condition de course)​

Quand le resultat depend de l'ordre d'execution non determine.

Thread 1                 Thread 2
-------- --------
Lire compteur (= 5)
Lire compteur (= 5)
Incrementer (= 6)
Incrementer (= 6)
Ecrire (= 6)
Ecrire (= 6)

Resultat: 6 au lieu de 7!

Section Critique​

Zone de code qui accede a une ressource partagee et doit etre executee par un seul thread a la fois.

Deadlock (Interblocage)​

Situation ou deux threads s'attendent mutuellement indefiniment.

Thread 1: Detient A, attend B
Thread 2: Detient B, attend A
-> Blocage permanent!

Mecanismes de Synchronisation Windows​

Vue d'ensemble​

MecanismePorteeUtilisation
Critical SectionIntra-processusAcces rapide, meme processus
MutexInter-processusExclusion mutuelle, nomme
SemaphoreInter-processusControle d'acces multiple
EventInter-processusSignalisation
InterlockedIntra-processusOperations atomiques simples

Critical Section​

Concept​

Mecanisme leger pour synchroniser des threads au sein d'un meme processus.

Caracteristiques​

  • Plus rapide que Mutex
  • Limite a un seul processus
  • Non nomme

Utilisation (C/C++)​

CRITICAL_SECTION cs;
InitializeCriticalSection(&cs);

EnterCriticalSection(&cs);
// Section critique - un seul thread a la fois
compteur++;
LeaveCriticalSection(&cs);

DeleteCriticalSection(&cs);

En PowerShell (simulation)​

# Utilisation de [System.Threading.Monitor]
$lockObj = New-Object Object
$compteur = 0

[System.Threading.Monitor]::Enter($lockObj)
try {
# Section critique
$compteur++
}
finally {
[System.Threading.Monitor]::Exit($lockObj)
}

Mutex (Mutual Exclusion)​

Concept​

Objet de synchronisation permettant l'exclusion mutuelle entre processus.

Caracteristiques​

  • Peut etre nomme (accessible entre processus)
  • Plus lent que Critical Section
  • Detection de deadlock possible

Utilisation en PowerShell​

# Creer ou ouvrir un mutex nomme
$mutexName = "Global\MonMutex"
$mutex = New-Object System.Threading.Mutex($false, $mutexName)

try {
# Attendre le mutex (timeout 5 secondes)
if ($mutex.WaitOne(5000)) {
try {
Write-Host "Mutex acquis - section critique"
# Travail exclusif ici
Start-Sleep -Seconds 2
}
finally {
$mutex.ReleaseMutex()
Write-Host "Mutex libere"
}
}
else {
Write-Host "Timeout - mutex non acquis"
}
}
finally {
$mutex.Close()
}

Mutex nomme vs anonyme​

TypeNomPortee
AnonymeAucunThreads du meme processus
Local"Local\Nom"Session utilisateur
Global"Global\Nom"Tous les processus systeme

Semaphore​

Concept​

Permet de limiter le nombre d'acces simultanees a une ressource.

Difference avec Mutex​

MutexSemaphore
1 seul accesN acces simultanees
Proprietaire uniquePas de proprietaire

Utilisation en PowerShell​

# Semaphore avec 3 places
$semName = "Global\MonSemaphore"
$semaphore = New-Object System.Threading.Semaphore(3, 3, $semName)

try {
if ($semaphore.WaitOne(5000)) {
try {
Write-Host "Place acquise dans le semaphore"
# Travail limite a 3 threads simultanees
Start-Sleep -Seconds 2
}
finally {
$semaphore.Release()
Write-Host "Place liberee"
}
}
}
finally {
$semaphore.Close()
}

Cas d'usage​

  • Pool de connexions base de donnees
  • Limitation de telechargements simultanees
  • Controle de ressources limitees

Event​

Concept​

Permet a un thread de signaler un evenement a d'autres threads.

Types d'events​

TypeComportement
AutoResetLibere un seul thread puis se remet a non-signale
ManualResetReste signale jusqu'a reset explicite

Utilisation en PowerShell​

# Event ManualReset
$eventName = "Global\MonEvent"
$event = New-Object System.Threading.EventWaitHandle(
$false, # Initial state: non signale
[System.Threading.EventResetMode]::ManualReset,
$eventName
)

# Dans le thread producteur
$event.Set() # Signaler
$event.Reset() # Remettre a non signale

# Dans le thread consommateur
if ($event.WaitOne(5000)) {
Write-Host "Event recu!"
}

$event.Close()

Interlocked Operations​

Concept​

Operations atomiques sur des variables, sans besoin de lock explicite.

Operations disponibles​

OperationDescription
IncrementIncremente de 1
DecrementDecremente de 1
AddAjoute une valeur
ExchangeEchange des valeurs
CompareExchangeEchange conditionnel

Utilisation en PowerShell​

# Increment atomique
$compteur = 0
[System.Threading.Interlocked]::Increment([ref]$compteur)
Write-Host "Compteur: $compteur"

# Add atomique
[System.Threading.Interlocked]::Add([ref]$compteur, 10)
Write-Host "Compteur apres add: $compteur"

# Exchange atomique
$oldValue = [System.Threading.Interlocked]::Exchange([ref]$compteur, 100)
Write-Host "Ancienne valeur: $oldValue, Nouvelle: $compteur"

Bonnes Pratiques​

Eviter les Deadlocks​

  1. Ordre constant: Toujours acquerir les locks dans le meme ordre
  2. Timeouts: Utiliser des timeouts pour detecter les blocages
  3. Minimiser: Garder les sections critiques courtes

Exemple de deadlock evite​

# MAUVAIS - risque de deadlock
# Thread 1: Lock A puis Lock B
# Thread 2: Lock B puis Lock A

# BON - ordre constant
# Thread 1: Lock A puis Lock B
# Thread 2: Lock A puis Lock B (meme ordre!)

Performance​

MecanismePerformanceCas d'usage
InterlockedTres rapideOperations simples
Critical SectionRapideMeme processus
MutexMoyenInter-processus
SemaphoreMoyenAcces multiple limite

Detection des Problemes​

Process Explorer​

  • View > Show Lower Pane
  • Handle view: voir les handles de synchronisation

WinDbg​

!locks          # Afficher les locks
!handle # Afficher les handles
!analyze -hang # Analyser un hang/deadlock

Performance Monitor​

Compteurs utiles:

  • Process > Handle Count
  • Thread > Context Switches/sec

Exercices​

  1. Creez un script avec deux jobs PowerShell qui utilisent un mutex partage
  2. Implementez un compteur thread-safe avec Interlocked
  3. Creez un semaphore qui limite a 2 executions simultanees

References​