Comment fonctionnent les acteurs par rapport aux threads?

88

Y a-t-il une bonne et courte explication du fonctionnement des acteurs par rapport aux threads?

Un fil de discussion ne peut-il pas être considéré comme un acteur et envoyer des messages à d'autres fils? Je vois une différence, mais ce n'est pas si clair pour moi. Puis-je utiliser des acteurs dans n'importe quelle langue en utilisant les threads différemment?

Jonas
la source

Réponses:

78

Le modèle de l'acteur fonctionne sur la transmission de messages. Les processus individuels (acteurs) sont autorisés à s’envoyer des messages de manière asynchrone. Ce qui distingue cela de ce que nous considérons normalement comme le modèle de filetage, c'est qu'il n'y a (en théorie du moins) aucun état partagé. Et si l'on croit (à juste titre, je pense) que l'état partagé est la racine de tout mal, alors le modèle de l'acteur devient très attractif.

Nous ne devrions cependant pas nous exciter. Le modèle de l'acteur ne rend pas (contrairement à certaines allégations) impossible les blocages. Le modèle d'acteur ne vous empêche pas non plus d'avoir des conflits de ressources entre différents processus - des files d'attente de messages, par exemple. Le modèle est uniquement "sans verrouillage" au-dessus d'un certain niveau. À un niveau inférieur, pour coordonner les files d'attente de messages, le verrouillage est toujours nécessaire.

Un fil de discussion ne peut-il pas être considéré comme un acteur et envoyer des messages à d'autres fils?

Eh bien, oui et non. Non, si vous utilisez simplement l'approche consistant à placer des mutex autour des emplacements de mémoire partagés. Ensuite, les threads partagent cet état - ils ont tous les deux accès à cette mémoire, peuvent à la fois la lire, la réécrire, etc. sous. J'ai piraté quelque chose comme ça (très mal) en donnant à chaque thread une file d'attente gardée par un mutex - juste pour le plaisir. Pour avoir une idée de la gestion de l'impédance des fils d'acteur, consultez ma question d'il y a un an .

Puis-je utiliser le modèle d'acteur dans n'importe quelle langue en utilisant les threads différemment?

Oui, mais cela demandera un peu plus de travail. Votre langue préférée pourrait bien avoir une bibliothèque de transmission de messages, ce serait donc la première chose à étudier. En outre, vous devez étudier l'utilisation de structures de données immuables. Notez que si une structure de données est immuable, alors vous avez essentiellement traité le problème de "l'état partagé" - plusieurs threads peuvent contenir des références à des données immuables sans que rien de mal ne se produise. Il y a une raison pour laquelle les langages d'acteurs ont tendance à être aussi des langages fonctionnels (erlang, scala).

Vous voudrez peut-être également jeter un coup d'œil à la mémoire transactionnelle logicielle, qui est un modèle différent mais aussi convaincant. Clojure en est mon exemple préféré.

Rob Lachlan
la source
3
Plus j'utilise des modèles de simultanéité basés sur le passage de messages asynchrones (par exemple, les acteurs ou async / await), plus je pense qu'ils sont simplement doubles de l'ancien modèle standard de simultanéité de blocage synchronisé. Le passage de messages asynchrones n'est pas vraiment plus facile ni plus difficile que d'utiliser des verrous et des moniteurs. En effet, il n'y a pas d'état mutable partagé, mais seulement au niveau d'un seul acteur . Mais un acteur a toujours un état mutable, et il est en fait observable par tous les acteurs qui coopèrent avec lui. Par conséquent, vous pouvez avoir tous les mêmes problèmes: impasses, livelocks, famine, conditions de course, etc.
Piotr Kołaczkowski
2

Je ne dirais pas que les acteurs transmettent toujours des messages de manière asynchrone - ce serait trop lent. Par exemple, le projet JActor utilise des messages bidirectionnels (demande / réponse) pour mieux modéliser un appel de méthode. Et la plupart des demandes sont traitées de manière synchrone.

JActor (une bibliothèque Java) n'utilise pas non plus de verrous. Seules quelques structures de données atomiques et concurrentes, avec quelques sémaphores jetés. Le passage de messages représente environ 0,8 milliard de messages par seconde.

https://github.com/laforge49/JActor

Bill la Forge
la source
2
Le modèle d'acteur est défini en utilisant uniquement la communication asynchrone ( en.wikipedia.org/wiki/Actor_model ). Si JActor ne fait pas cela, alors ce n'est pas à 100% seulement le modèle d'acteur. Il peut simplement utiliser le modèle d'acteur comme l'une de ses nombreuses fonctionnalités.
BT