/* Page prose (fr) */
"SemaphoreAsLock" = "# Un sémaphore de 1 en guise de verrou (et pourquoi s'en méfier)\n\nMets le compte à **1** et un sémaphore devient un **verrou**, une porte qu'une seule tâche peut franchir à la fois. Tout ce qui se trouve entre `wait()` et `signal()` est une **section critique**: du code qui doit s'exécuter sans qu'un autre thread ne l'interrompe.\n\nPourquoi aurais-tu besoin de ça? Parce que deux tâches touchant la même variable à la fois peuvent la corrompre. Le code ci-dessous a 500 tâches qui incrémentent chacune un compte partagé.";
"SemaphoreAsLock-2" = "**Observe l'exécution:** tu obtiens `500`, à chaque fois.\n\n* callout(Essaie): Commente les lignes `lock.wait()` et `lock.signal()` et exécute-le quelques fois. Tu obtiendras un nombre *inférieur* à 500, et un nombre différent à chaque exécution. C'est une **data race**: sans le verrou, plusieurs tâches lisent la même valeur de `seen`, chacune ajoute un, et chacune réécrit le même résultat, donc ces incréments s'effondrent en un seul. Le verrou force la lecture et l'écriture à se produire comme une seule unité, donc aucune mise à jour n'est perdue.\n\nÇa marche, mais recours-y avec précaution. Un sémaphore de compte 1 a la même comptabilité fragile que `enter`/`leave`: oublie un `signal()` sur un chemin d'erreur et toutes les autres tâches attendent pour toujours (un **interblocage**). Il bloque aussi de vrais threads pendant qu'ils font la queue. Pour une simple exclusion mutuelle il existe des outils plus légers et plus sûrs (une file en série, ou `NSLock`), et la réponse moderne de Swift, les **actors**, fait de ce genre de protection d'état partagé une fonctionnalité du langage que tu ne peux pas oublier d'équilibrer. Tu affronteras la course elle-même de plein fouet au chapitre suivant, et les actors plus loin dans le livre. Pour l'instant, sache seulement: un sémaphore *peut* être un verrou, mais \"verrou\" n'est pas son meilleur emploi.\n\n[Précédent](@previous)  |  page 7 sur 8  |  [Suivant: Récapitulatif](@next)";
