10
votes

Y a-t-il des conceptions simultanées où le modèle d'acteur n'est pas bon?

J'ai remarqué que toutes les conceptions que j'ai rencontrées peuvent être multi-threads à l'aide du mode acteur - séparant chaque module de travail en un acteur différent et à l'aide d'une file d'attente de message (pour moi un .NET Concurrentqueue) pour passer des messages. Quels autres bons modèles multi-filetés existent?


1 commentaires

Je pense que le manque d'attention de votre question est devenu possible, car peu de gens sont enseignés ce genre de chose. Les gens découvrent le filetage dans le contexte des sémaphores, de la mémoire partagée, etc., et généralement c'est tout. Les tenues telles que Microsoft font de leur mieux pour masquer les threads du programmeur - Tâches dans une piscine de fil, IO asynchrone avec des événements d'achèvement, etc. csp elle-même est un calcul de processus, et si cette phrase ne met pas le programmateur moyen que je n'ai pas t sais ce qui va! Le résultat de cet enseignement médiocre est que beaucoup de programmeurs trouvent des threads durs et un peu effrayant.


5 Réponses :


13
votes
Je pense que

Communiquer des processus séquentiels est un modèle bien meilleur pour la concurrence que le modèle Acteur. Il aborde un certain nombre de problèmes avec le modèle de l'acteur (et d'autres modèles) tels que l'impasse, Livelock, Starvation. Jetez un coup d'œil à Ceci et, plus utile pratiquement utile, Ceci .

La principale différence est la suivante: Dans le modèle Acteur, un message est envoyé de manière asynchrone. Cependant, dans les messages CSP sont envoyés de manière synchrone; L'expéditeur ne peut pas envoyer tant que le récepteur est prêt à recevoir.

Cette simple restriction simplifie le monde de la différence. Si vous avez une conception incorrecte avec un potentiel d'impasse, alors dans le modèle de l'acteur, il peut ne pas se produire (et il ne se produit généralement que lorsque vous démolez au patron ...). Cependant, dans CSP, l'impasse se produira toujours, vous laissant sans aucun doute que votre conception est incorrecte. Ok, alors tu dois toujours le réparer mais ça va. Les problèmes de fixation que vous savent sont qu'il est beaucoup plus facile que de tenter de tester de manière exhaustive pour l'absence de problèmes (votre seul choix dans le modèle de l'acteur).

L'approche strictement synchrone du CSP semble semblable à des problèmes de temps de réponse; Par exemple, on craint qu'un thread d'interface graphique ne puisse pas passer à autre chose parce qu'il n'a pas été en mesure d'envoyer un message à un fil de travailleurs occupé qui n'a pas aussi loin que sa «lecture». Ce que vous avez à faire est de vous assurer que la charge de travail est répartie sur suffisamment de threads afin qu'ils puissent tous récupérer de nouveaux messages dans une période de temps acceptable. Le CSP ne vous permet pas de vous échapper. Le modèle de l'acteur ne fait cependant pas être trompé; Vous construisez juste des problèmes futurs.

in .NET A Concurrentqueue n'est pas la bonne primitive pour le CSP, pas à moins que vous couche un mécanisme de synchronisation sur le dessus. J'ai ajouté une synchronisation stricte au-dessus des sockets TCP aussi. En fait, j'arrive généralement à écrire une sorte de bibliothèque qui résoudra à la fois des prises et des tuyaux de sorte qu'elle devienne immatérielle de savoir si un «processus» (comme ils sont connus dans le langage CSP) est un fil sur cette machine ou un autre processus sur une autre machine à la fin d'une connexion réseau. Nice - Scalabilty construit depuis le tout début.

Je l'ai fait la voie du CSP depuis 23 ans maintenant, je ne le ferai pas d'autre manière. Construit de gros systèmes avec des milliers de fils de cette façon.

== EDIT ==

Il semble que cette réponse attire toujours une certaine attention, alors je pensais que j'ajouterais. Pour les développeurs Windows, il y a le Dataflow Espace de noms pour la bibliothèque parallèle de tâche. Il doit être téléchargé séparément. Microsoft Lesribe, ce modèle Dataflow favorise la programmation basée sur les acteurs en fournissant des messages en cours de passage pour des tâches de Dataflow et de pipeline à grains grossières. " Excellent! Il utilise des classes comme bufferblocks comme communication canaux. L'important est qu'un bufferblock ait un BLANDITEDCAPACITAITE PROPRIÉTAIRE DEMANDE À UN NON SOUNDÉE, qui correspond au modèle de l'acteur. Définissez ceci sur une valeur de 1, et vous l'avez maintenant transformé en une chaîne de communication de style CSP.


4 commentaires

Intéressant - il y aurait des avantages dans le test / le débogage avec l'envoi de message synchrone (pour détecter toutes les impasses), puis la désactivation par la suite de la synchronisation de la libération (par exemple, pour obtenir une meilleure performance, car l'envoi de threads n'aurait pas à attendre? ). En outre, quel type de "problèmes futurs" faisiez-vous référence au quatrième paragraphe? Épuisement de la mémoire?


@Jeremyfriesner - voir réponse séparée


@bazza hi, Je recherche un façon d'utiliser csp dans f # . Comment utiliseraflow pour cela?


@MamCx j'ai peur de ne rien savoir sur f #. Vraisemblablement, vous pouvez simplement utiliser Dataflow? Notez également que, tandis que vous pouvez vous rapprocher de CSP en définissant la capacité limitée à 1, car c'est vrai csp, il doit être 0.



7
votes

Pour ajouter à mon dernier, il existe divers autres modèles multi-threading au-delà du CSP. Ce page Wikipedia répertorie plusieurs autres comme CCS , ACP et lotos . Lire ces articles surviennent à une caverne profonde et noire où les universitaires errent, en attente de bonder sur un développeur de logiciels errants.

Le problème est que l'obscurité académique signifie souvent un manque total d'outils et de bibliothèques au niveau pratique et utilisable. Il faut beaucoup d'efforts pour convertir une étude académique saine et éprouvée dans un ensemble de bibliothèques et d'outils. Il y a peu d'incitation réelle pour la communauté logicielle plus large d'adopter un papier théorique et de la transformer en une réalité pratique.

J'aime le CSP car il est en fait mort simple à implémenter votre propre bibliothèque CSP en fonction de SELECT () ou PSélection (). Je l'ai fait plusieurs fois maintenant (je dois apprendre à propos de la réutilisation du code), plus les gentils personnes de l'université de Kent ont mis en place JCSP pour ceux qui aiment Java. Je ne recommande pas de développer à Occam (bien que ce soit toujours à peu près possible); Le soutien et la maintenabilité vont être des problèmes à l'avenir. Le CSP est probablement le plus facile à entrer et, compte tenu de ses bonnes caractéristiques, il vaut la peine.


4 commentaires

Venir réel bientôt maintenant est une nouvelle bibliothèque de Clojure Core.Async basée sur les idées de CSP et occam, mais a la prestation (sur JCSP) de ne pas être liée à de vrais threads.


La partie ASYNC est une écart par rapport à l'intention de CSP (strictement synchrone), et cela ressemble à la clojure ressemblera au modèle de l'acteur. Rien de mal avec ça bien sûr! La forme générale et l'architecture du modèle d'acteur et des systèmes CSP sont presque identiques. Cependant, la variante CSP est mathématiquement analysable (en raison de la synchronicité), tandis que la variante du modèle de l'acteur n'est pas. Ne pas être attaché à de vrais threads? Hmmm, ADA Runtimes l'habitude de le faire et je me souviens de la "journée glorieuse" (alors j'ai entendu dire) que le compilateur ADA de Greenhill pour VXWorks a commencé à utiliser de vrais threads!


@bazza Vous pouvez éditer vos réponses que vous savez, au lieu de laisser 3 réponses! ;-) Toutes les choses intéressantes, merci.


@Davidroussel, ils deviennent assez longtemps, n'est-ce pas! Content que ce soit intéressant, content d'être de service :)



6
votes

@jeremyfriesner

Problèmes futurs

Pour développer ce que je voulais dire par "problèmes futurs", je faisais référence au fait que dans un système asynchrone, l'expéditeur de messages n'a aucune connaissance de savoir si le récepteur assure réellement la demande. L'expéditeur ne sait pas car tout ce qu'il sait, c'est que certains messages tampon ont accepté le message. Le transport sous (E.G. TCP) s'allume ensuite avec le travail de repousser le message comme et lorsque le récepteur est prêt à l'accepter.

Ainsi, il se peut que, lorsqu'il soit sous contrainte, le système ne fonctionne pas selon les besoins, car le transport de message aura inévitablement une capacité limitée pour absorber les messages que le récepteur ne peut pas encore accepter. L'expéditeur ne le trouve que sur après le problème a déjà commencé à développer, au cours de laquelle il pourrait être trop tard pour faire quoi que ce soit à ce sujet.

Test de cours peut révéler ce problème, mais vous devez faire attention à ce que les tests aient vraiment épuisé la capacité du transport à absorber des messages. Juste une explosion rapide à pleine vitesse pourrait être tromper.

Bien sûr, un système synchrone impose une surcharge ("Êtes-vous déjà prêt?", "Non, pas encore", "Maintenant", "oui!", "Vous êtes alors") qui ne fait pas arriver dans un système asynchrone. Donc, en moyenne, le système asynchrone sera plus efficace, pourrait en réalité avoir un débit supérieur, etc., raison pour laquelle la plupart des systèmes du monde sont réellement asynchrones, mais aussi la raison pour laquelle les systèmes n'atteignent pas toujours la pleine capacité que les systèmes bruts Les largeurs de bande de réseau peuvent suggérer. Lors de l'approche de systèmes asynchrones à pleine capacité, il a tendance à ne pas limiter gracieusement, à mon avis. Bagus de jeton (NB pas anneau de jeton) était un bon exemple de réseau synchrone avec un débit totalement fiable et déterministe, mais n'était qu'un peu plus lentement que la bague Ethernet et de jeton ...

Après avoir toujours été bénie avec une surpasse de bande passante dans mes problèmes, j'ai choisi la route synchrone pour des raisons de certitude de succès; Je ne perds pas vraiment beaucoup sur la bande passante, mais je perds des tonnes de risque, ce qui est bon.

convertir de synchrone en asynchrone

Peut-être, mais c'est peut-être peu de valeur. Dans un système synchrone, il ne fonctionne que selon l'exigence si vous avez équilibré avec succès la division du travail entre les threads. C'est-à-dire que suffisamment de threads font les bits lents de sorte que les bits rapides ne soient pas retenus. Obtenez ce problème et le système n'est certainement pas assez rapide.

Mais après avoir fait que vous avez un système où chaque composant est capable d'envoyer des messages sans retard, car tout ce qu'il envoie est prêt et en attente (en raison de vos compétences et de votre jugement pour équilibrer les charges de travail). Donc, si vous avez fait ensuite convertir en un moyen de transport d'un message asynchrone, tout ce que vous faites, vous économiserons de faibles quantités de temps dans le transport de ces messages. Vous n'effectuez pas de modifications qui entraîneront des charges de travail rapidement rapidement. Cependant, si l'économie de bande passante est l'objectif, peut-être peut-être sa valeur.

Bien sûr, faire cet équilibrage peut être une chose difficile et traiter des variables telles que les heures d'accès au disque dur, les réseaux, etc. peut être difficile à surmonter. J'ai souvent dû mettre en œuvre un système de partage de la charge de travail «Suivant disponible». Mais certainement dans des systèmes de traitement du signal de temps réel telles que ceux que je joue avec vous, vous traitez essentiellement d'un transport très fiable comme le Rapidio de OpenVPX, vous ne faites que des sommes sur les données (ne pas traiter des bases de données, des disques, etc.) et Les taux de données sont très élevés (1 gbyte / s est parfaitement faisable ces jours-ci et, en fait, je manipulais des taux de données qui sont élevés il y a 13 ans; c'était le travail Haaard). Être strictement synchrone signifie que vous suivez certainement le taux de données ou non. Avec asynchrone, c'est plus d'un ...

OS en temps réel pour tout le monde!

Avoir un système d'exploitation en temps réel est également un composant essentiel et ces jours-ci, il semble que ce soit le patch Preempt_rt pour Linux qui fait le travail pour beaucoup de personnes dans le commerce. Redhat Faites un essai préparé de celui-ci (RedHat Mrg), mais pour un Greebie Scientific Linux des gens sympa du CERN est bon et gratuit! Je soupçonne fortement que de nombreux systèmes travailleraient beaucoup plus facilement près de leurs limites de capacité si Preempt_rt était utilisé - il fait un bon travail de lissage des choses.


0 commentaires

4
votes

La concurrence est un sujet fascinant avec de nombreuses approches de la mise en œuvre avec la question fondamentale - "Comment puis-je coordonner des calculs parallèles?" . .

Certains modèles de concurrence sont:

Futures

futures également appelé promesses ou sont des objets sont des objets qui agissent comme des procurations pour un résultat calculé de manière asynchrone. Lorsque la valeur est en réalité nécessaire pour un calcul, le thread gèle jusqu'à ce que le calcul soit terminé et que la synchronisation soit obtenue.

Les contrats à terme sont le modèle de concurrence préféré pour .NET et es6 .

Logiciels Mémoire Transactionnelle

Mémoire transactionnelle logicielle (STM) synchronise l'accès à la mémoire partagée (beaucoup comme des verrous) en regroupant des actions dans les transactions. Toute transaction unique ne voit qu'une seule vue de la mémoire partagée et est atomique. Ceci est conceptuellement similaire à combien de bases de données traitent de la concurrence.

STM est le modèle de concurrence préféré pour Clojure et Haskell .

le modèle d'acteur

le modèle de l'acteur se concentre sur le passage du message. Un acteur reçoit un message et peut décider d'envoyer un message en réponse, de reproduire d'autres acteurs, de faire des changements locaux, etc. C'est probablement le modèle le moins étroitement couplé de ceux-ci par rapport aux acteurs échange uniquement des messages et rien d'autre.

Le modèle Acteur est le modèle de concurrence préféré pour Erlang et Rust .


Notez que, contrairement aux langues mentionnées ci-dessus, la plupart des langues ne disposent pas de canon ni de modèles de simultanées préférées et même ces langues qui indiquent une préférence solide pour un modèle ont généralement les autres mis en œuvre comme des bibliothèques.

Mon opinion personnelle est que l'expulsion d'avenir STM et les acteurs de la simplicité d'utilisation et de raisonnement, mais aucun de ces modèles n'est intrinsèquement "faux" et je ne peux penser à aucun inconvénient pour. Vous pouvez utiliser ce que vous préférez sans conséquences.


1 commentaires

La rouille utilise csp et non le modèle d'acteur, voir Lars.com/concurrency/rust/servo/2013/12/21/...



1
votes

Le modèle le plus général pour le traitement parallèle est Trets Petri . Il représente un calcul comme un graphe de dépendance pure de données, qui expresse le parallélisme maximal. Tous les autres modèles découlent de celui-ci.

Modèle informatique de Dataflow http://www.cs.colostate.edu/cameron/dataflow .html , 0 commentaires