100% ont trouvé ce document utile (1 vote)
842 vues4 pages

Exercices Corrigés Semaphore

Le document présente plusieurs exercices sur la gestion de ressources concurrentes en utilisant des sémaphores. Chaque exercice aborde un problème spécifique, comme la gestion d'une ressource unique, la synchronisation de producteurs et consommateurs, la barrière de synchronisation, le problème des philosophes dineurs, et la gestion des accès en lecture et écriture. Des algorithmes et des explications sont fournis pour chaque cas afin d'illustrer l'utilisation des sémaphores pour éviter les interblocages et garantir un accès correct aux ressources.

Transféré par

ismailbouchriha09
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
100% ont trouvé ce document utile (1 vote)
842 vues4 pages

Exercices Corrigés Semaphore

Le document présente plusieurs exercices sur la gestion de ressources concurrentes en utilisant des sémaphores. Chaque exercice aborde un problème spécifique, comme la gestion d'une ressource unique, la synchronisation de producteurs et consommateurs, la barrière de synchronisation, le problème des philosophes dineurs, et la gestion des accès en lecture et écriture. Des algorithmes et des explications sont fournis pour chaque cas afin d'illustrer l'utilisation des sémaphores pour éviter les interblocages et garantir un accès correct aux ressources.

Transféré par

ismailbouchriha09
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Exercice 1 : Gestion d'une Ressource Unique

Un serveur peut traiter une seule requête à la fois. Lorsqu'une nouvelle requête arrive, elle
doit attendre que le serveur soit libre. Proposez un algorithme utilisant des sémaphores pour
gérer l'accès au serveur.

●​ Indication : Utilisez un sémaphore binaire pour contrôler l'accès à la ressource.

Sémaphore binaire mutex = 1

Process Requête() {
wait(mutex)
// Accès au serveur
TraiterRequête()
signal(mutex)
}

Explication :

●​ Le sémaphore mutex initialise à 1 (libre).


●​ wait(mutex) permet à une seule requête d'accéder au serveur.
●​ Une fois la requête traitée, signal(mutex) libère le serveur.

Exercice 2 : Synchronisation de Producteurs et Consommateurs

Dans un système de production, plusieurs producteurs déposent des éléments dans un


tampon partagé, et plusieurs consommateurs les retirent. Le tampon a une capacité limitée.
Proposez un algorithme pour synchroniser les producteurs et les consommateurs en utilisant
des sémaphores.

●​ Indication : Utilisez des sémaphores compteurs pour gérer le nombre d'éléments


dans le tampon et l'espace disponible.

Sémaphore compteur empty = N // Capacité du tampon

Sémaphore compteur full = 0 // Nombre d'éléments dans le tampon

Sémaphore binaire mutex = 1 // Accès au tampon

Process Producteur() {

wait(empty)

wait(mutex)
// Ajouter un élément au tampon

signal(mutex)

signal(full)

Process Consommateur() {

wait(full)

wait(mutex)

// Retirer un élément du tampon

signal(mutex)

signal(empty)

Explication :

●​ empty contrôle l'espace libre.


●​ full contrôle le nombre d'éléments présents.
●​ mutex protège l'accès concurrent au tampon.

Exercice 3 : Barrière de Synchronisation

Un groupe de threads doit atteindre un point de synchronisation avant de continuer leur


exécution. Une fois que tous les threads ont atteint la barrière, ils peuvent continuer.
Proposez un algorithme utilisant des sémaphores pour implémenter cette barrière.

●​ Indication : Utilisez un sémaphore binaire pour contrôler le passage à travers la


barrière et un compteur pour suivre le nombre de threads ayant atteint la barrière.

int count = 0
int total_threads = N
Sémaphore binaire mutex = 1
Sémaphore binaire barrier = 0

Process Thread() {
wait(mutex)
count++
if (count == total_threads) {
signal(barrier)
}
signal(mutex)

wait(barrier)
signal(barrier)
}

Explication :

●​ mutex protège l'incrémentation de count.


●​ barrier est signalé une fois que tous les threads ont atteint la barrière.
●​ La dernière opération signal(barrier) permet à tous les threads de passer.

Exercice 4 : Philosophe Dîneur

Cinq philosophes sont assis autour d'une table circulaire, chacun ayant une assiette de
spaghettis. Entre chaque paire de philosophes se trouve une seule fourchette. Un
philosophe ne peut manger que s'il a les deux fourchettes adjacentes. Proposez un
algorithme pour éviter les situations de famine et de blocage en utilisant des sémaphores.

●​ Indication : Utilisez des sémaphores binaires pour représenter les fourchettes, et


assurez-vous que l'algorithme évite les interblocages.

Sémaphore binaire fourchette[5] = {1, 1, 1, 1, 1}

Process Philosophe(int i) {
wait(fourchette[i])
wait(fourchette[(i+1) % 5])
// Manger
signal(fourchette[i])
signal(fourchette[(i+1) % 5])
}

Explication :

●​ Chaque philosophe prend d'abord la fourchette à sa gauche, puis à sa droite.


●​ Les sémaphores binaires fourchette assurent qu'une seule personne utilise une
fourchette à la fois.
●​ Pour éviter l’interblocage, on peut modifier l'algorithme pour qu'un philosophe prenne
toujours d'abord la fourchette la plus basse, puis la plus haute (ou inversement).
Exercice 5 : Lecture et Écriture Concurrentes

Dans une base de données, plusieurs lecteurs peuvent lire en même temps, mais l'écriture
doit être exclusive. Proposez un algorithme utilisant des sémaphores pour gérer les accès
en lecture et en écriture.

●​ Indication : Utilisez un sémaphore pour protéger l'accès en écriture et un compteur


pour gérer le nombre de lecteurs.

int lecteur_count = 0
Sémaphore binaire mutex = 1
Sémaphore binaire write = 1

Process Lecteur() {
wait(mutex)
lecteur_count++
if (lecteur_count == 1) {
wait(write)
}
signal(mutex)

// Lire

wait(mutex)
lecteur_count--
if (lecteur_count == 0) {
signal(write)
}
signal(mutex)
}

Process Écrivain() {
wait(write)
// Écrire
signal(write)
}

Explication :

●​ mutex protège l'incrémentation et la décrémentation de lecteur_count.


●​ write empêche les écrivains d’accéder pendant la lecture.
●​ Le premier lecteur bloque l'accès en écriture, et le dernier lecteur libère l'accès.

Vous aimerez peut-être aussi