Ma description du modèle d'acteur est-elle correcte?

13

Si j'ai bien compris, le modèle acteur est exactement comme le modèle objet, mais avec quelques différences:

  1. CHAQUE objet génère son propre thread séparé et ce n'est pas un problème même lorsque vous avez des milliers d'objets.
  2. Les acteurs n'interagissent pas en appelant des fonctions et en obtenant des valeurs de retour, mais en envoyant et en recevant des messages.
  3. Si vous ne violez pas ce modèle, votre application utilisera la concurrence à sa pleine puissance sans aucun risque de conditions de concurrence.
  4. Tout ce que vous pouvez faire en OO, vous pouvez le faire en utilisant des acteurs mais mieux, le problème étant que tout ce que nous avons codé au cours des dernières années était basé sur OO - mais une transition est imminente.

Donc, par exemple, supposons que je doive définir une classe / un acteur de vecteur 3D, créer deux instances et appeler une opération de somme sur elles.

OBJET ORIENTÉ:

class V3d {
   constructor V3d(x,y,z) //bla
   float x,y,z;
   function sum(V3d b) 
   { 
      return V3d(x+b.x,y+b.y,z+b.z); 
   }
}

//using:
mySum = V3d(1,2,3).sum(V3d(3,2,1)) //creates 2 instances, sum, returns instantly
drawPoint(mySum) //uses the result

MODÈLE D'ACTEUR:

actor V3d 
{
    constructor V3d(x,y,z) //bla
    float x,y,z;
    loop 
    {
       receive 'sum',b:V3d :
           send(caller,'sumResult',V3d(x+b.x,y+b.y,z+b.z))
    }
 }

//using:
send(V3d(1,2,3),'sum',V3d(3,2,1)) //creates 2 instances, send to the first one a request to sum with the second one

loop 
{
   receive 'sumResult',result:
      drawPoint(result) //receives result and draws it
}

Est-ce que c'est ça? Ou je me trompe complètement?

WindScar
la source
Les acteurs légers, les micro-agents ou les composants de flux de données n'utilisent pas nécessairement leur propre thread. :-) Vérifiez les termes suivants: programmation basée sur les acteurs, programmation basée sur les agents, programmation basée sur les flux de données. Ils sont très similaires, mais ils ont des contraintes différentes. Ohh je vais poser cette question ;-)
inf3rno

Réponses:

12

La réponse courte est non, ce n'est pas correct.

  1. commence raisonnablement correct (chaque acteur s'exécute au moins potentiellement comme un thread indépendant), mais sort ensuite largement des rails. Il n'y a rien dans le modèle qui fait que beaucoup de threads fonctionnent bien - cela dépend de l'implémentation. Tout au plus, la facilité de création d'un grand nombre de threads exerce une pression sur l'implémentation pour fournir un threading efficace. Du moins en ce qui concerne le modèle, toute ressemblance entre les acteurs et les objets est principalement une coïncidence. "Objet" a des implications assez spécifiques sur la façon dont vous combinez le code et les données. Un acteur impliquera généralement à la fois du code et des données, mais implique peu sur la façon dont ils sont combinés (à part le fait que les seules données visibles par le monde extérieur sont les messages).

  2. La façon habituelle de décrire l'interaction consiste à envoyer des messages, oui. Je n'ai pas de citation à portée de main, mais quelqu'un a prouvé il y a longtemps que des mécanismes comme les fonctions virtuelles C ++ sont isomorphes à l'envoi de messages (car les fonctions virtuelles sont normalement implémentées, vous utilisez un décalage dans une table virtuelle - mais si vous envoyé un décalage dans une table de messages à la place, l'effet serait le même).

  3. Ce n'est pas aussi simple que cela. Si vous pouvez en trouver une copie, Henry Baker (avec quelqu'un d'autre dont je ne me souviens pas du nom pour l'instant) a écrit un article sur les règles nécessaires à la cohérence des données dans le modèle Actor.

  4. "Mieux" est au mieux très subjectif. Certains problèmes sont de nature très parallèle et impliquent vraiment un grand nombre d'entités essentiellement autonomes, avec une interaction minimale principalement asynchrone. Lorsque c'est le cas, le modèle d'acteur peut très bien fonctionner. Pour d'autres problèmes, ce n'est vraiment pas le cas. Certains problèmes sont presque entièrement de nature sérielle. D'autres peuvent être exécutées en parallèle, mais nécessitent toujours une synchronisation étroite entre ces actions (par exemple, essentiellement un mode de type SIMD, où vous exécutez une instruction à la fois, mais chaque instruction agit sur un grand nombre d'éléments de données). Il est certainement possible de résoudre ces deux types de problèmes en utilisant le modèle de l'acteur - mais pour de tels problèmes, cela implique souvent une quantité considérable de travail supplémentaire pour un gain faible ou nul en retour.

Jerry Coffin
la source
Il n'y a pas de relation entre le nombre d'acteurs et le nombre de threads; ce que le modèle d'acteur garantit, c'est qu'une instance donnée ne sera exploitée que par un seul thread à la fois, donc vos acteurs sont déjà thread-safe et vous n'avez pas besoin d'utiliser des stratégies de synchronisation et de verrouillage à l'intérieur.
Rob Crawford
@RobCrawford: c'est une façon (assez banale) d'assurer la cohérence des données dans le modèle Actor. Le papier Hewitt / Baker couvre plus de possibilités, telles que plusieurs copies d'un acteur s'exécutant dans des threads séparés (hmm ... en regardant ma réponse, je me demande si je ne pouvais honnêtement pas me souvenir du nom de Carl Hewitt à l'époque, ou était ironique quand je l'ai écrit).
Jerry Coffin du
L' asynchronisme du message passant n'est-il pas un élément essentiel du modèle? Cela l'empêcherait sûrement d'être isomorphe avec les appels de fonctions virtuelles, qui sont de nature synchrone. Ou la distinction n'est-elle pas pertinente d'un certain point de vue?
boycy le
2

Concernant 1: J'ai travaillé avec une application modélisée par un acteur (ish), il est donc tout à fait possible d'ignorer le grand nombre de threads que cela suggère. AFAIK, les threads ne sont en aucun cas des objets légers, il n'est donc probablement pas souhaitable d'en avoir un pour chaque acteur, selon le nombre d'acteurs que vous utilisez.

Concernant 3: je suis presque sûr que les conditions de concurrence peuvent se produire dans les systèmes modélisés par des acteurs simplement en raison de la logique de programmation?

Concernant 4: Définir «mieux»? D'après mon expérience, la logique asynchrone peut être beaucoup plus difficile à lire que les éléments synchrones. Par exemple, dans votre exemple ci-dessus, vous ne savez pas quelle opération est responsable de quel résultat, il y a donc un suivi supplémentaire des messages à faire. Une fois que cela est ajouté et que d'autres messages entrants et sortants sont inclus dans la logique, l'intention du code est répartie sur plusieurs fonctions d'envoi / réception.

Cela dit, je suis un grand fan de l'utilisation du modèle d'acteur pour les couches supérieures d'une application. Cela peut faciliter le découplage, car l'ajout de dépendances est un peu plus difficile que l'ajout d'une fonction. Je n'ai pas non plus beaucoup d'expérience avec un niveau supérieur aux langages Java, et d'autres paradigmes pourraient prendre en charge l'asynchronisme d'une manière plus fondamentale.

remorqueurs
la source
Concernant # 1: Eh bien, "thread" peut faire référence à beaucoup de choses. Les threads d'OS sont généralement assez lourds, certes, mais il existe des exécutions de langage qui gèrent en interne des centaines, des milliers, voire des millions de "threads" d'exécution dans un petit nombre de threads d'OS. Dans certaines implémentations, ces modèles évoluent apparemment jusqu'à des dizaines de cœurs (j'ai vu des déclarations selon lesquelles les versions récentes du GHC fonctionnent bien avec 32 cœurs).