2010-07-14 6 views
0

J'essaie de travailler sur une bibliothèque de passage de messages microthread en C# en utilisant mono. Depuis Mono 2.4 ou plus, des continuations apparentes (pas de rendement) ont été disponibles sous 'Mono.Tasklets'. Cependant, ceux-ci manquent de toute documentation que je peux trouver, et tandis que mon utilisation générale d'entre eux fonctionne, j'obtiens un plantage occasionnel (mais reproductible) auquel le débogueur ne s'attachera pas.Crash using Mono.Tasklets.Continuation

Mes questions spécifiques sont:

Est-ce que quelqu'un sait ce que la fonction Mark() est, et où/quand je dois l'appeler? Cela semble être une initialisation unique, mais je ne sais pas pourquoi cela ne serait pas dans le constructeur alors.

Y a-t-il des limites à l'utilisation de plusieurs suites? J'ai découvert que vous ne pouvez pas passer une continuation à un autre thread, mais il semble que je peux stocker plusieurs suites et basculer en arrière et en avant?

Répondre

2

LE: En ce qui concerne le problème de plantage voir ces bugs ouverts: Bug 566324, Bug 580791, Bug 602502

Je suis assez nouveau pour moi-même, je vous présente ici les informations que je recueillies à ce jour. Peut-être que ce sera utile.

1) La bibliothèque Mono.Tasklets (décrite par Miguel de Icaza [READ: here]) est une bibliothèque de continuation qui peut être utilisée pour construire diverses formes de systèmes de continuation et de threads légers (LW).

Une manière simple d'imaginer ceci est la version mono du longjmp/setjmp de C, ils peuvent seulement être utilisés pour dérouler la pile.

La bibliothèque a été initialement développé par un gars [LIRE: here] et maintenant il est inclus dans Mono et documenté [LIRE: here] (suivre les liens et vous trouverez plus d'informations)

Ce gars-là a mis en œuvre un Bibliothèque de microthreading au-dessus de cette abstraction. 2) Une continuation est un objet qui peut être utilisé pour stocker l'état d'exécution en cours et qui peut ensuite être utilisé pour restaurer l'état stocké plus tard. Par "état d'exécution", on entend ici la pile, qui comprend la pile d'appel et les variables locales, ainsi que les registres du processeur.

Lorsque l'état stocké est restauré, l'exécution du programme a l'air de revenir à la position où l'état a été sauvegardé, avec toutes les variables locales restaurées.

An example in C. et plus d'informations sur Wikipedia/Continuations

3) L'API est:

public class Continuation { 
     public Continuation(); 
     public void Mark(); 
     public int Store (int state); 
     public void Restore (int state); 
} 

continuations peuvent être utilisés pour mettre en œuvre microfiletages. Vous pouvez regarder le code de Mono.Microfiletages disponible sur GitHub [LIRE: here]

public Continuation() 
    { 
     m_handle = alloc_continuation(); 
     Print("Continuation()"); 
    } 

    public void Mark() 
    { 
     Print("Mark()"); 
     // skip 1 frame, ie. this function 
     mark_continuation_frame(m_handle, 1); 
    } 

    public int Store(int data) 
    { 
     Print("Store({0})", data); 
     int res = store_continuation(m_handle, data); 
     Print("Store({0}) = {1}", data, res); 
     return res; 
    } 

    public void Restore(int data) 
    { 
     Print("Restore({0})", data); 
     restore_continuation(m_handle, data); 
     Print("Restore() exit (NEVER REACHED)"); 
    } 

De ce qui est présenté here:

Mark() il est utilisé pour marquer le plus haut cadre à stocker

Store (x) stocke l'état actuel dans la continuation et renvoie l'entier x donné.

restauration (y) restaure l'état stocké, et renvoie l'ordonnée entier donné. (Notez que l'y entier donné à restaurer est effectivement retourné par la méthode Store(), parce que nous en sommes là après que l'état a été restauré.)

static void Main() 
{ 
Continuation c = new Continuation(); 
c.Mark(); 
int foo = 123; 
int val = c.Store(0); 
Console.WriteLine("{0} {1}", val, foo); 
foo = 321; 
if (val < 5) 
    c.Restore(val + 1); 
} 

Lorsque vous appelez Store() l'état actuel de la l'exécution est enregistrée et il est possible de revenir à cet état en invoquant Restore().

L'appelant Store() indique si c'est le premier magasin ou un point de restauration en fonction du résultat de magasin:

var c = new Continuation(); 
... 

switch (c.Store (0)){ 
case 0: 
     // First invocation 
case 1: 
     // Restored from the point ahead. 
} 
... 
// Jump back to the switch statement. 
c.Restore (1); 
+0

Le lien Monoco + votre résumé en particulier a été extrêmement utile - merci! –