Si j'utilise des verrous, mon algorithme peut-il toujours être sans verrouillage?


9

Une définition courante du verrouillage sans verrou est qu'au moins un processus progresse. 1

Si j'ai une structure de données simple telle qu'une file d'attente, protégée par un verrou, alors un processus peut toujours progresser, car un processus peut acquérir le verrou, faire ce qu'il veut et le libérer.

Répond-il donc à la définition de verrouillage sans verrou?


1 Voir par exemple M. Herlihy, V. Luchangco et M. Moir. Synchronisation sans obstacle: files d'attente à double extrémité, par exemple. Dans Distributed Computing, 2003. "Il est sans verrou s'il garantit seulement que certains threads progressent toujours".


3
J'ai toujours compris «sans verrouillage» pour décrire une structure de données et un ensemble d'algorithmes qui n'utilisent pas de verrous, juste un petit ensemble défini d'opérations de mémoire atomique. Par exemple drdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/…
Paul Johnson

Réponses:


16

Ce n'est pas une définition de verrouillage sans verrou.

Si vous pouvez garantir des progrès, vous avez sans blocage , et si vous avez finalement terminé chaque demande, alors vous avez sans faim , mais pas sans verrouillage.

Je me demande si votre simple exemple le fournit de toute façon. Vous avez besoin de hiérarchies de verrous et ainsi de suite pour réellement garantir la progression lorsque plusieurs verrous sont impliqués.


1
J'utilise la définition de M. Herlihy. Une méthodologie pour implémenter des objets de données hautement simultanés. Transactions on Programming Languages ​​and Systems, 1993. "La condition de verrouillage garantit que certains processus progresseront toujours malgré les échecs d'arrêt arbitraires ou les retards d'autres processus"
Joe Pension

12
@Joe: Ce n'est pas une définition, cela décrit une implication. Méfiez-vous de l'erreur logique de l'inverse.
Ben Voigt

2
Pourrait également citer M. Herlihy, V. Luchangco et M. Moir. Synchronisation sans obstacle: files d'attente à double extrémité, par exemple. Dans Distributed Computing, 2003. "Il est sans verrou s'il garantit seulement que certains threads progressent toujours".
Joe Pension

1
il y a aussi la famine gratuite qui est plus spécifique que l'impasse (chaque processus peut aller, peu importe ce que font les autres processus) notez que les boucles CaS (basées sur les primitives atomiques) ne le sont pas
ratchet freak

5
@Joe: Si le reste du monde considère que cette propriété est sans blocage , alors je vais utiliser ce terme. Non, votre exemple simple n'est pas sans impasse. Afin de garantir que quelque chose est sans blocage, vous avez non seulement besoin d'une synchronisation, mais d'une garantie qu'aucun thread n'effectuera d'opération de blocage tout en maintenant le verrou. «faire ce qu'il veut» est extrêmement vague et ne semble pas fournir cette garantie.
Ben Voigt

11

J'ai étudié The Art of Multiprocessor Programming 1 et leur texte manque de clarté, tout comme le livre auquel vous vous référez. Voici quelques citations de TAMPP:

Citation 1 (Définition de sans verrou)

Une méthode est sans verrouillage si elle garantit que, infiniment souvent, un appel de méthode se termine en un nombre fini d'étapes.

Citation 2 (Définition de non blocage)

un appel en attente d'une méthode totale n'est jamais nécessaire pour attendre qu'un autre appel en attente se termine.

Citation 3 (affirmer que le verrouillage est non bloquant)

Les conditions de progression non bloquante sans attente et sans verrouillage garantissent que le calcul dans son ensemble progresse, indépendamment de la façon dont le système planifie les threads.

Le problème est que la revendication de la citation 3 ne découle évidemment pas de la définition de la citation 1. Comme déjà mentionné, une file d'attente synchronisée semble satisfaire la citation 1: infiniment souvent, une méthode réussit à acquérir le verrou et à se terminer.

Notez spécifiquement la phrase assez vague de la citation 3: "indépendamment de la façon dont le système planifie les threads". Ceci n'est précédé d'aucune sorte de description formelle du «système d'ordonnancement des threads», il nous reste donc à reconstruire ses propriétés en fonction de nos idées préconçues sur ce que les définitions devraient signifier:

  1. le système exécute toujours les instructions d' un thread;
  2. il ne peut jamais exécuter les instructions d'un thread donné ;
  3. tous les threads invoquent la méthode considérée.

Sur un tel système, une méthode de blocage ne peut pas être sans verrou: si le thread qui détient le verrou n'est plus jamais planifié pour exécution, il n'y aura pas d'autre thread qui puisse terminer son invocation de méthode en un nombre fini d'étapes, mais il y aura certains threads qui exécutent des étapes de la méthode. Pour un système plus réaliste, celui qui garantit de donner éventuellement du temps CPU à chaque thread, la définition doit inclure explicitement la propriété non bloquante:

Définition corrigée du verrouillage sans verrouillage

Une méthode est sans verrouillage si elle n'est pas bloquante et, en outre, garantit que infiniment souvent un appel de méthode se termine en un nombre fini d'étapes.

1 Maurice Herlihy, Nir Shavit, The Art of Multiprocessor Programming, Elsevier 2008, pp. 58-60


1
Le libellé de la citation 1 est vraiment étrange. Que veulent-ils dire par «infiniment souvent»? Évidemment, quelque chose de différent de "toujours", donc c'est ok que la méthode ne retourne jamais dans "certains" cas?
Hulk

Oui, le langage imprécis abonde. Qu'est-ce que "souvent" de toute façon? Je pense qu'ils signifient "dans une histoire d'exécution infinie, cet événement particulier se produit infiniment de fois".
Marko Topolnik

5

La terminologie n'est pas toujours cohérente, mais je pense que l'important est de poser les questions suivantes sur un algorithme ou un système proposé:

  1. Y a-t-il une séquence d'événements où les threads pourraient se coincer en attendant les uns les autres, même si tous les threads étaient autorisés tout le temps CPU qu'ils pouvaient utiliser [si c'est le cas, ce n'est pas sans blocage]
  2. Si un thread était bloqué pendant une durée arbitraire, cela pourrait-il bloquer d'autres threads ou nuire au fonctionnement du système pendant une durée arbitraire [si c'est le cas, ce n'est pas non bloquant].
  3. Existe-t-il une combinaison au moins théoriquement possible de la programmation des threads qui pourrait obliger tous les threads à répéter les mêmes opérations à plusieurs reprises tout en invalidant le travail des autres, sans que personne ne progresse [si c'est le cas, ce n'est pas sans verrou]
  4. Si certains threads ont suffisamment de temps CPU par rapport à un autre, pourraient-ils forcer ce dernier à continuer à réessayer indéfiniment [si c'est le cas, ce n'est pas sans attente].

Une grande partie de la signification des algorithmes sans verrouillage n'est pas qu'ils sont plus rapides que les algorithmes sans verrouillage, mais plutôt le fait qu'ils ne sont pas enclins à mourir si un thread est égaré [notez qu'une telle garantie nécessite simplement que les algorithmes ne soient pas bloquants, mais tous les algorithmes sans verrouillage le sont]. Il est possible qu'un algorithme sans verrouillage utilise des verrous, mais uniquement si les tentatives d'acquisition de verrouillage incluent des délais d'expiration avec des algorithmes pour garantir qu'il sera toujours possible pour quelqu'un de progresser (par exemple, un algorithme pourrait utiliser une CompareExchangeboucle comme son principal) méthode d'arbitrage, mais utilisez des verrous pour arbitrer l'accès lorsque la contention semble élevée; si un verrou semble être maintenu trop longtemps, d'autres threads pourraient décider d'abandonner les efforts pour utiliser ce verrou et en créer un nouveau.CompareExchange, le fait que les clients abandonnent le verrou ne compromettrait pas la cohérence du système, bien que cela puisse signifier que le code qui détenait l'ancien verrou ne fera aucun travail tant qu'il n'abandonnera pas l'ancien verrou et ne se mettra pas en ligne pour le nouveau.


Ceci est différent de la terminologie standard: votre 2. fait référence à la signification standard de non-blocage tandis que 3. fait référence à la liberté de verrouillage.
Marko Topolnik

J'ai vu des utilisations terminologiques incohérentes et je ne connais pas de norme "officielle". Le plus important est qu'il existe différentes garanties qu'un algorithme peut offrir, et il est important d'utiliser un algorithme qui offre des garanties suffisantes pour répondre aux exigences de l'application. De nombreux articles ne couvrent que certaines des garanties ci-dessus, mais il y a des cas où chacun peut être en mesure de satisfaire aux exigences de la demande plus facilement que toute autre garantie qui répondrait aux exigences.
supercat

Je pense qu'il existe un consensus sur le fait que la terminologie présentée dans The Art of Multiprocessor Programming est "standard".
Marko Topolnik

@MarkoTopolnik: Je vais alors éditer le post pour l'adapter. Aimez-vous la nouvelle version?.
supercat

Cool, très sympa.
Marko Topolnik

4

Vous devez regarder la "définition" que vous citez dans son contexte :

La manière traditionnelle de mettre en œuvre des structures de données partagées consiste à utiliser l'exclusion mutuelle (verrous) pour garantir que les opérations simultanées n'interfèrent pas entre elles. Le verrouillage présente un certain nombre d'inconvénients en ce qui concerne l'ingénierie logicielle, la tolérance aux pannes et l'évolutivité (voir [8]). En réponse, les chercheurs ont étudié une variété de techniques alternatives de synchronisation qui n'utilisent pas l'exclusion mutuelle . Une technique de synchronisation est sans attente si elle garantit que chaque thread continuera à progresser malgré le retard (ou même l'échec) arbitraire des autres threads. Il est sans verrou s'il garantit uniquement que certains threads progressent toujours.

Vous utilisez des verrous pour l'exclusion mutuelle, ce n'est donc pas une technique sans verrouillage dont ils parlent.


2

Si j'utilise des verrous, mon algorithme peut-il toujours être sans verrouillage?

C'est possible, mais cela dépend de l'algorithme.

Si j'ai une structure de données simple telle qu'une file d'attente, protégée par un verrou, alors un processus peut toujours progresser, car un processus peut acquérir le verrou, faire ce qu'il veut et le libérer.

Répond-il donc à la définition de verrouillage sans verrou?

Remarque en soi .

Si l' étape "faire ce qu'il veut" n'implique pas l'acquisition d'autres verrous, et qu'elle est garantie de se terminer dans un temps fini, alors cette partie particulière de votre algorithme sera sans blocage.

Cependant, si ces conditions préalables ne sont pas remplies, il y a au moins le risque de blocages ...


Après avoir étudié le texte de L'art de la programmation multiprocesseur, je suis arrivé à la conclusion que les mutex invalident définitivement la définition de verrouillage sans verrouillage, lorsque la définition est correctement énoncée. J'ai ajouté une réponse à cette page pour clarifier cela.
Marko Topolnik

1

L'exemple que vous donnez n'est pas sans verrouillage pour la raison suivante.

La prise en charge d'un thread acquiert le verrou et le planificateur du système d'exploitation a suspendu le thread pendant une période solitaire infinie, puis tout le thread ne peut pas progresser car personne ne peut acquérir le verrou acquis par le thread suspendu.

De manière générale, les algorithmes qui utilisent des verrous ne sont pas sans verrouillage.

Notez que sans blocage et sans verrouillage sont deux concepts différents. sans interblocage signifie qu'il n'y a aucune possibilité d'impasse, mais il pourrait y avoir des livelocks qui pourraient empêcher l'ensemble du système de progresser. La liberté de verrouillage est plus forte que cela, car cela signifie que certains threads du système progressent toujours avec un nombre fini d'étapes.


Regardez une définition plus prudente sur Wikipédia: "Un algorithme est sans verrouillage s'il satisfait que lorsque les threads du programme sont exécutés suffisamment longtemps, au moins l'un des threads progresse." Cela exclut le cas de l'arrêt des threads. Les progrès en cours d'arrêt sont également couverts par la liberté d'obstruction , et non par la liberté de verrouillage .
Marko Topolnik

@MarkoTopolnik Votre commentaire n'a aucun sens. La liberté de verrouillage couvre la liberté d'obstruction. Tout ce qui est sans verrou doit être sans obstacle. Et la définition que vous avez donnée n'exclut pas l'arrêt des discussions.
Chaoran

Veuillez prendre soin de faire la distinction entre «donner du sens» et «être correct». Mon commentaire est incorrect, comme le montre ma réponse suivante. Mais la définition de Wikipédia est également erronée ou du moins ambiguë.
Marko Topolnik

@MarkoTopolnik Puisque vous admettez que votre commentaire n'est pas correct, vous devez le supprimer pour éviter de dérouter les autres lecteurs. Wikipédia est souvent incorrect ou ambigu. Vous devriez trouver des définitions subtiles comme "liberté de verrouillage" dans des articles académiques tels que cs.rochester.edu/~scott/papers/2006_PPoPP_synch_queues.pdf (la définition de verrouillage-libre est dans la section 2.1)
Chaoran

Oui, l'inclusion de la propriété non bloquante dans la définition de la liberté de verrouillage est une façon de le faire. Cela a été indiqué dans une révision antérieure de ma réponse.
Marko Topolnik
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.