2009-07-28 6 views
3

Dans le contexte de la synchronisation des structures de données, quelqu'un peut-il clarifier la différence entre «sans verrou» et «non bloquant»? Ces termes semblent être utilisés de manière interchangeable par beaucoup de gens mais je ne suis pas encore sûr s'il n'y a pas quelque différence subtile cachée quelque part. Je veux dire que lockless est «sans verrou» et que le blocage est plus proche de la garantie de progression. Je soupçonne que l'un implique l'autre mais pas l'inverse, je ne suis pas sûr.Quelle est la différence entre lockless et non-bloquant?

Références Bienvenue.

+0

"Non-bloquant" est probablement le mieux pensé en termes d'éviter les risques de progression (et pourrait même impliquer des verrous d'essorage et des threads en interne). Chaque appel de fonction retourne en temps opportun ou retourne un travail partiel (un rendement de co-routine, une promesse, ou des rappels une fois terminé). Le verrouillage est une stratégie d'exactitude qui a l'exactitude - les dangers et les risques de progrès, tels que la mort-en-tenant-serrure et la loi d'amdahls. Une autre stratégie de correction-non-verrouillage et de stratégie de progression invoquant des propriétés commutatives (structures sans verrou, immuables) pourrait être appropriée. – Rob

Répondre

6

Le verrouillage est un mécanisme de contrôle d'accès. Par où je veux dire que vous verrouillez une ressource lorsque vous voulez un accès exclusif à celle-ci. Verrouillez la porte, utilisez la pièce/faites ce que vous voulez, maintenant déverrouillez la pièce pour les autres, afin qu'ils puissent l'utiliser maintenant. Alors que la pièce est verrouillée, personne d'autre n'aurait pu entrer dans la pièce, donc n'aurait rien pu faire.

Le blocage est utilisé pour la récupération de données garantie, à moins que vous ne possédiez pas de données, ne revenez pas. Continuez à attendre à la porte/tuyau/prise (fondamentalement n'importe quoi) et quand les données sont disponibles l'obtiennent et reviennent.

Addition--
Ne pas confondre par le littéral anglais-sens des mots, car les deux peuvent être utilisés échange-habilement dans le contexte que vous essayez de les mettre dans Par exemple -. verrouillage est comme en bloquant pour que d'autres utilisent la même ressource, et en bloquant peut être en verrouillant vous-même (en appelant la fonction) à la ressource jusqu'à ce que les données soient disponibles. Donc, VERROUILLAGE signifie simplement que vous capturez une ressource pendant un certain temps (sauf si vous la débloquez). Et, BLOQUANT vous êtes bloqué, ce qui signifie que vous ne pouvez pas aller plus loin car vous n'avez pas de données, pour continuer ou continuer.

La façon dont ils sont implémentés, en changeant les états du processus, et en attendant que l'interruption ou l'événement se produise.

+0

Si je comprends bien, les verrous bloquent? –

+0

@Helltone - En général, un verrou ne bloque que si quelqu'un d'autre l'utilise déjà. –

+1

Ces commentaires sont confus pour moi. Donc, vous dites que «sans verrou» signifie que l'accomplissement des autres ne dépend pas de soi et «non bloquant» signifie que l'accomplissement de soi ne dépend pas des autres. C'est ce que tu veux dire? –

1

Oui, sans dispositif de verrouillage. Non-bloquant signifie qu'un appel va revenir immédiatement plutôt que d'attendre un événement externe (tel que la libération d'un verrou ou l'arrivée de données dans un tampon). Il est possible d'avoir des serrures et utiliser des appels non-blocage, comme par exemple dans l'appel

flock(fh, LOCK_SH | LOCK_NB); 

qui signifie « essayer d'obtenir un verrou de lecture, mais si vous ne pouvez pas, n'attendez pas pour un, reviens immédiatement et dis-moi que tu ne pouvais pas ". Le comportement par défaut de LOCK_SH ("verrou partagé") sans LOCK_NB ("non-bloquant") serait d'attendre la disponibilité du verrou.

3

Ils sont totalement différents. Verrouiller signifie que vous utilisez une méthode pour contrôler l'accès aux fichiers à l'aide de verrous. Cela arrête deux processus qui écrivent dans le même fichier en même temps, arrête une écriture pendant qu'une autre est en train de lire, mais permet à deux de lire en même temps. Le blocage signifie que le procédé attendra que l'opération se termine avant de revenir.

Mise à jour

En réponse à la demande des exemples ... Je vais essayer d'ajouter des exemples si je reçois le temps, mais pour l'instant, voici une explication des possibilités.

Nous avons 3 façons d'effectuer le verrouillage:

  • Aucun
  • Blocking. Si le verrou est indisponible, attendez-le.
  • Non bloquant. Si le verrou est indisponible, échoue.

Et 2 façons d'effectuer IO:

  • bloquante. Attendez que les tampons soient prêts.
  • Non bloquant. Échouer si nous ne pouvons pas lire/écrire immédiatement

Si nous utilisons open() et read() comme d'habitude, nous obtenons le blocage IO. Si nous voulons des E/S non bloquantes, nous devons passer le drapeau O_NONBLOCK à open(), et read() retournera alors E_AGAIN au lieu de bloquer.

Par défaut, il n'y a pas de verrouillage. Nous pouvons appeler fcntl() avec F_SETLK ou F_SETLKW pour obtenir le verrou.Le premier bloque si le verrou est indisponible, ce dernier échoue avec EACCES ou EAGAIN.

Je pense qu'il ya deux points de confusion possibles:

  • IO peut être le blocage/non-blocage, de verrouillage peut être le blocage/non-blocage. Outre les données qui ne sont pas prêtes, une demande d'E/S peut bloquer car un autre processus a verrouillé le fichier.
+0

Le verrouillage n'est pas seulement utilisé pour l'accès aux fichiers, mais je comprends votre réponse. Je ne suis pas sûr qu'ils soient "totalement" différents, peut-être que l'un implique l'autre? ou dans certains contextes, ils sont identiques mais pas en général. Alors ma question est: quels contextes? –

+0

Bien sûr, le verrouillage s'applique à toutes sortes d'accès - l'accès aux fichiers n'est qu'un exemple facile. Ce sont des problèmes orthogonaux et vous pouvez avoir l'un ou l'autre sans l'autre. – Draemon

+0

@Draemon "vous pouvez avoir l'un ou l'autre sans l'autre". Les exemples seraient vraiment les bienvenus ici. –

1

Ils peuvent être similaires, mais souvent utilisés dans des contextes différents. Dans le contexte d'une structure de données, ce serait la même chose. Vous pouvez également utiliser "non-bloquant" dans le contexte d'E/S, auquel cas cela signifie que la fonction n'attendra pas que l'opération soit terminée avant de revenir ou que l'opération soit sûre de ne pas bloquer (par exemple lire des données qui ont déjà été mis en cache). De plus, le fait de ne pas bloquer peut ne pas impliquer que quelque chose est sans verrou. Par exemple, une structure de données peut utiliser des verrous mais avoir certaines opérations non bloquantes qui ne nécessitent pas de verrou et d'autres opérations de blocage qui en nécessitent une.

0

Une tentative de réponse par un exemple:

Tenir compte d'un objet (appelé "événement") avec deux méthodes, wait() et notify().

  • Application 1:

    notify() définit atomiquement un booléen. wait() boucles jusqu'à ce que le booléen est vrai. Les deux sont sans verrou, mais wait() est bloquant.

  • Mise en œuvre 2:

    notify() obtient un verrou, définit une valeur booléenne libère alors le verrou. wait() obtient le verrou, lit le booléen, libère le verrou, tout ceci dans une boucle jusqu'à ce que le booléen soit vrai. Les deux sont ainsi , bloquant.

  • Mise en œuvre 3:

    Dans un premier temps le verrou est en cours d'utilisation. notify() vérifie un booléen et libère le verrou si c'est vrai. wait() obtient le verrou et définit le booléen à true. notify() est non-bloquant (il est discutable si c'est sans verrou ou non). wait() est verrouillé, bloquant.

Je dirais donc que non bloquant implique lockless, mais ils ne sont pas équivalentes parce qu'un lockless opération peut bloquer encore une condition dans une boucle.

Questions connexes