2008-10-06 4 views

Répondre

-1

Ma première impulsion (je ne suis pas un expert):

avoir un verrou sur cet objet que le code utilise pour écrire à elle. Lorsque vous effectuez une copie en profondeur, verrouillez l'objet, effectuez votre copie en profondeur, puis déverrouillez-le.

Ou, il me manque quelque chose ici?

+1

Pas aussi facile que cela puisse paraître, étant donné que c'est une copie profonde qui est impliqué ici. Il y a potentiellement beaucoup de verrous sur différentes parties de données dans le graphe d'objets. Très, très facile d'en manquer un ou de l'impasse. – Andrew

4

Dépend de vos structures de données.

Je suppose que le problème auquel vous faites face (même si vous ne le dites pas) est l'inversion de verrouillage potentielle. Si vous effectuez une copie en profondeur, vous devrez probablement prendre un ou plusieurs verrous pour les différents objets que vous devez copier.

Si vous pouvez définir un DAG (c'est-à-dire un ordre partiel) où les nœuds sont tous les verrous du système, et si chaque combinaison de verrous que vous voulez prendre est connectée par des arêtes, vous pouvez vous assurer que ne sont jamais prises dans des ordres différents dans des threads différents. Donc, en particulier, vous n'obtiendrez pas d'inversion de verrouillage. Une règle typique consiste à prendre le verrou "le plus général" en dernier, car cela tend à minimiser les conflits. Mais si vous copiez en profondeur l'un des nombreux "WidgetBox", contenant chacun des "Widgets" qui sont fondamentalement indiscernables, avec un chevauchement possible entre le contenu des boîtes, alors vous avez un problème pour définir un ordre de verrouillage naturellement. En outre, vous devez d'abord verrouiller la WidgetBox (même si c'est l'objet "le plus général"), car sans ce verrou, vous ne pouvez pas dire quoi d'autre vous devez verrouiller. Si les Widgets sont comparables, vous pouvez les verrouiller dans l'ordre, faire votre copie et tout relâcher. Méchant.

Une alternative consiste à définir un seul verrou partagé entre tous les Widgets et les WidgetBox. Ceci peut introduire beaucoup de contention, auquel cas le verrouillage optimiste peut améliorer les choses, à condition qu'il n'y ait pas trop de modifications simultanées avec les copies. Une autre alternative peut être d'assouplir les garanties que vous faites sur la copie - au lieu d'exiger que la copie complète soit faite à partir d'un état identifiable de la structure profonde, vous pouvez d'abord verrouiller la WidgetBox, peu profonde (en utilisant refcounting ou Quoi que ce soit - le verrou sur un refcount est typiquement un "verrou interne ultime" et donc pas un risque d'inversion), libérez le verrou WidgetBox, puis copiez chacun des Widgets à tour de rôle. Utilisez la même approche pour copier les Widgets s'ils ont une structure interne. Le résultat peut contenir un Widget dans un état qu'il n'a pas atteint avant d'avoir été retiré de la WidgetBox dans un autre thread, ou d'autres incongruités, donc si ce n'est pas acceptable, vous ne pouvez pas utiliser cette approche. Mais si vous ne verrouillez qu'un seul objet à la fois dans chaque thread, vous ne pouvez pas verrouiller l'inversion.

Une dernière option possible, "nucléaire", est de rendre tout ce qui est immuable, et de toujours le copier en cas de modification. Si rien ne peut être modifié, vous n'avez pas besoin de verrous (bien que vous ayez toujours besoin de barrières de mémoire lors de la transmission de références entre les threads).

Si aucun de ces travaux ne fonctionne, alors vous êtes hors de mon expérience, sauf si j'ai oublié quelque chose. Je suppose que la mise en œuvre de la base de données est quelque part que beaucoup d'habileté liée à la serrure se passe, et ce serait le domaine à se tourner vers des idées.

0

fork()

Je plaisante.Mais c'était trop drôle de laisser passer :)

Je pense que onebyone a couvert la plupart de vos options. Sauf, peut-être, en revenant et en voyant si vous pouvez trouver un moyen d'éviter de faire la copie profonde en premier lieu ...

Questions connexes