Article de reference

implémentation du modèle d'acteur

En informatique , l'implémentation du modèle d'acteur concerne les problèmes d'implémentation du modèle d'acteur . Cube cosmique Le Cosmic Cube de Caltech a été développé par Ch...

informatique , l'implémentation du modèle d'acteur concerne les problèmes d'implémentation du modèle d'acteur .

Cosmic Cube de Caltech a été développé par Chuck Seitz et al. à Caltech, offrant un support architectural pour les systèmes d'acteurs. Une différence majeure entre le Cosmic Cube et la plupart des autres processeurs parallèles réside dans le fait que cette machine MIMD (Multiple Instruction, Multiple Data) utilise le passage de messages , plutôt que des variables partagées, pour la communication entre les processus concurrents. Ce modèle de calcul se reflète dans l'architecture matérielle et le système d'exploitation , et correspond également à la communication par passage de messages explicite perçue par le programmeur. Selon Seitz [1985] :

L'expérience Cosmic Cube reposait sur le principe que la communication inter-nœuds devait être facilement extensible à un très grand nombre de nœuds. Un réseau direct comme l'hypercube répond à cette exigence, tant en termes de bande passante agrégée atteinte grâce aux nombreux canaux de communication simultanés que de faisabilité de la mise en œuvre. L' hypercube est en réalité une variante distribuée d'un réseau à commutation logarithmique indirecte , tel que les réseaux Omega ou Banyan : dans les organisations à stockage partagé, on utilise généralement des chemins de communication uniformes. Cependant, avec l'architecture de l'hypercube, les chemins de communication peuvent emprunter un nombre variable de canaux, ce qui engendre des latences différentes. Il est ainsi possible d'optimiser les performances en plaçant les processus sur les nœuds en fonction de la localité de communication.

Machine J

La J-Machine a été développée par Bill Dally et al. au MIT et offre un support architectural adapté aux acteurs. Ce support comprend notamment les éléments suivants :

  • Messagerie asynchrone
  • Un espace uniforme d'adresses d'acteurs auquel des messages peuvent être envoyés simultanément, que l'acteur destinataire soit local ou non.
  • Une forme de filière d'acteurs (voir modèle d'acteur )

Smalltalk concurrent (qui peut être modélisé à l'aide d'acteurs ) a été développé pour programmer la machine J.

Langage de programmation d'acteurs prototype

Hewitt [2006] a présenté un prototype de langage de programmation d'acteurs , en ce sens qu'il exprime directement des aspects importants du comportement des acteurs. Les messages sont exprimés en XML à l'aide de la notation suivante : :<tag>[<element>1 ... <element>] for

<<tag>><element>1 ... <element>n<”/<tag>>

La sémantique du langage de programmation est définie en représentant chaque élément du programme comme un acteur doté de son propre comportement. L'exécution est modélisée par l'échange de messages Eval entre ces éléments lors de l'exécution.

acteurs environnementaux

Chaque Evalmessage contient l'adresse d'un acteur qui représente un environnement, associé à des identifiants de programme. Les acteurs d'environnement sont immuables ; ils ne changent pas. Lorsqu'un Request[Bind[identifier value] customer]acteur d'environnement reçoit un message, un nouvel acteur d'environnement est créé. Si ce nouvel acteur reçoit un message, il envoie un autre message Request[Lookup[identifier’] customer’]si le message identifierest identique au identifier’message reçu customer’Returned[value], sinon il envoie un autre message Environment Request[Lookup[identifier’] customer’]. Ce mécanisme repose sur un acteur EmptyEnvironmentqui, lorsqu'il reçoit un message Request[Lookup[identifier] customer], envoie un autre message . Lorsqu'il reçoit une requête, il agit de la même manière .customerThrown[NotFound[identifier]]BindEmptyEnvironmentEnvironment

Expressions

Le langage de programmation prototype comporte des expressions des types suivants :

< identifier >
Dès Request[Eval[environment] customer]réception, envoyezenvironmentRequest[Lookup[<identifier>] customer]
envoyer < destinataire > < communication >
Lorsque Request[Eval[environment] customer]vous recevez ceci, envoyez " où est un nouvel acteur tel que"<recipient>Request[Eval[environment] evalCustomer1]evalCustomer1
lorsqu'il reçoit la communication , alors envoyerevalCustomer1Returned[theRecipient]<communication>
Request[Eval[environment] evalCustomer2]où se trouve un nouvel acteur tel queevalCustomer2
lorsqu'il reçoit la communication , alors envoyez-la .evalCustomer2Returned[theCommunication]theRecipienttheCommunication
< destinataire > . < message >
Dès Request[Eval[environment] customer]réception, envoyez de sorte que<recipient>Request[Eval[environment] evalCustomer1]
lorsqu'il reçoit la communication , alors envoyez de sorte queevalCustomer1Returned[theRecipient]<message>Request[Eval[environment] evalCustomer2]
lorsqu'il reçoit la communication , alors envoyerevalCustomer2Returned[theMessage]theRecipient
Request[theMessage customer]
récepteur ... < motif > i < expression > i ...
Dès Request[Eval[environment] customer]réception, envoyez customerun nouvel acteur theReceivertel que
lorsqu'il theReceiverreçoit une communication com, créez un nouvel bindingCustomerenvironnement d'envoi.
Request[Bind[<pattern>i com] bindingCustomer]et
si bindingCustomerreçoit Returned[environment’], envoyer<expression>i
Request[Eval[environment’]]
sinon, si bindingCustomerreçoit Thrown[...], essayez<pattern>i+1
comportement ... < motif > i < expression > i ...
Dès Request[Eval[environment] customer]réception, envoyez au client un nouvel acteur theReceivertel que
lorsqu'il theReceiverreçoit Request[message customer’], alors créez-en un nouveau bindingCustomeret envoyez-leenvironment
Request[bind[<pattern>i message] customer’]et
  1. si bindingCustomerreçoit Returned[environment’], envoyer<expression>i
    Request[Eval[environment’] customer’]
  2. sinon, si bindingCustomerreçoit Thrown[...], essayez<pattern>i+1
{ < expression > 1 , < expression > 2 }
Lorsqu'il Request[Eval[environment] customer]est reçu, envoyez-le et envoyez simultanément .<expression>1Request[Eval[environment]]<expression>2Request[Eval[environment]] customer]
soit < identifier > = < expression > valeur dans < expression > corps
Une fois message[Eval[environment] customer]reçu, créez-en un nouveau evalCustomeret envoyez-le.<expression>value
Request[Eval[environment] evalCustomer1.
Lorsqu'il evalCustomerreçoit Returned[theValue], créez-en un nouveau bindingCustomeret envoyez-leenvironment
Request[bind[<identifier> theValue] bindingCustomer]
Lorsque bindingCustomerreçoit Returned[environment’], envoyer<expression>bodyRequest[Eval[environment’] customer]
sérialiseur < expression >
Lorsqu'il Request[Eval[environment] customer]est reçu, envoyez-le à customerReturned[theSerializer]l'endroit où theSerializerse trouve un nouvel acteur tel que les communications envoyées à theSerializersoient traitées dans l'ordre FIFO avec un acteur de comportement qui est initialement et<expression>.Eval[environment]
Lorsque la communication comest reçue par theSerializer, alors envoyez l'acteur de comportement Request[com customer’]customer’est un nouvel acteur tel que
lorsque customer’reçoit Returned[theNextBehavior]alors theNextBehaviorest utilisé comme acteur de comportement pour la prochaine communication reçue par theSerializer.

Exemple de programme

Voici un exemple de programme pour une cellule de stockage simple pouvant contenir n'importe quelle adresse d'acteur :

Cellule ≡
récepteur
Demande[Créer[client initial]]
envoyer client Retourné[ sérialiseur ReadWrite(initial)]

Le programme ci-dessus, qui crée une cellule de stockage, utilise le comportement ReadWrite défini comme suit :

LireÉcrire(contenu) ≡
comportement
Demande[lire[] client]
{ envoyer client Returned[contents], ReadWrite(contents)}
Demande[écrire[x] client]
{ envoyer client Returned[], ReadWrite(x)}

Le comportement décrit ci-dessus est encapsulé, c'est-à-dire que le traitement d'un message de lecture ou d'écriture précédent peut se poursuivre pendant le traitement d'un message de lecture ou d'écriture suivant. Par exemple, l'expression suivante crée une cellule x avec le contenu initial 5, puis y écrit simultanément les valeurs 7 et 9.

soit x = Cell.Create[5] dans {x.write[7], x.write[9], x.read[]}

La valeur de l'expression ci-dessus est 5, 7 ou 9.