Le livre "Compétitivité et concurrence sur la plate-forme .NET. Modèles de conception efficaces "

image Salut, habrozhiteli! Le livre de Riccardo Terrell fournit des conseils sur la façon de créer des programmes compétitifs et évolutifs dans .NET, soulignant les avantages d'un paradigme fonctionnel et fournissant les outils et principes appropriés pour maintenir la concurrence de manière compétitive et facile. En conséquence, armé de nouvelles compétences, vous recevrez les connaissances nécessaires pour devenir un expert dans la fourniture de solutions performantes performantes.

Si vous écrivez du code multithread dans .NET, ce livre peut vous aider. Si vous souhaitez utiliser un paradigme fonctionnel pour simplifier la programmation compétitive et maximiser les performances des applications, ce livre sera un guide important pour vous. Il bénéficiera à tout développeur .NET qui souhaite écrire des applications compétitives, réactives et asynchrones qui évoluent et s'adaptent automatiquement aux ressources matérielles existantes partout où de tels programmes fonctionnent.

Structure de publication: feuille de route


Les quatorze chapitres de ce livre sont divisés en trois parties. La partie I présente les concepts fonctionnels de la programmation compétitive et décrit les compétences nécessaires pour comprendre les aspects fonctionnels de la rédaction de programmes multithread.

  • Le chapitre 1 décrit les concepts et objectifs de base de la programmation compétitive, ainsi que les raisons d'utiliser la programmation fonctionnelle pour écrire des applications multithreads.
  • Le chapitre 2 explore une gamme de technologies de programmation fonctionnelle pour améliorer les performances des applications multithread. Le but de ce chapitre est de fournir au lecteur les concepts utilisés dans le reste du livre et d'introduire des idées puissantes qui découlent d'un paradigme fonctionnel.
  • Le chapitre 3 donne un aperçu du concept fonctionnel d'immuabilité. Il explique comment l'immuabilité est utilisée pour écrire des programmes compétitifs prévisibles et corrects et pour mettre en œuvre des structures de données fonctionnelles qui sont de nature sécurisée pour les threads.

Dans la partie II, divers modèles de programmation compétitive dans un paradigme fonctionnel sont examinés en profondeur. Nous explorerons des sujets tels que la bibliothèque parallèle de tâches (TPL) et implémenterons des modèles parallèles tels que Fork / Join, diviser et conquérir et MapReduce. Cette section traite également de la présentation déclarative, des abstractions de haut niveau dans les opérations asynchrones, de la programmation des agents et de la sémantique de transfert de messages.

  • Le chapitre 4 décrit les bases du traitement parallèle de grandes quantités de données, y compris des modèles tels que Fork / Join.
  • Le chapitre 5 présente des méthodes plus sophistiquées pour le traitement parallèle de grandes quantités d'informations, telles que l'agrégation parallèle, la réduction des données et la mise en œuvre d'un modèle MapReduce parallèle.
  • Le chapitre 6 fournit des informations détaillées sur les méthodes fonctionnelles de traitement des flux d'événements (données) en temps réel à l'aide des opérateurs fonctionnels de haut niveau dans .NET Reactive Extensions pour former des combinateurs d'événements asynchrones. Les méthodes étudiées seront ensuite utilisées pour implémenter un modèle réactif éditeur-abonné compétitif.
  • Le chapitre 7 fournit une explication du modèle de programmation basé sur les tâches appliqué à la programmation fonctionnelle pour la mise en œuvre d'opérations concurrentielles à l'aide du modèle Monadic. Ensuite, cette méthode est utilisée pour construire un pipeline compétitif basé sur un paradigme de programmation fonctionnelle.
  • Le chapitre 8 est consacré à l'implémentation de l'informatique parallèle illimitée à l'aide du modèle de programmation asynchrone C #. Ce chapitre traite également des méthodes de gestion des erreurs et des méthodes de construction d'opérations asynchrones.
  • Le chapitre 9 décrit le flux de travail asynchrone en F #. Il montre comment une évaluation différée et explicite dans ce modèle permet une sémantique de composition plus élevée. Ensuite, nous apprendrons comment implémenter des expressions de calcul personnalisées pour élever le niveau d'abstraction à la programmation déclarative.
  • Le chapitre 10 montre comment, sur la base des connaissances acquises dans les chapitres précédents, des combinateurs et des modèles, tels que Functor, Monad et Applicative, peuvent être implémentés pour composer et exécuter plusieurs opérations asynchrones et gérer les erreurs sans effets secondaires.
  • Le chapitre 11 analyse la programmation réactive à l'aide d'un modèle de messagerie logicielle. Il révèle le concept d'isolement naturel en tant que technologie qui complète l'immuabilité et permet la création de programmes compétitifs. Ce chapitre se concentre sur la classe MailboxProcessor utilisée en F # pour distribuer le travail parallèle à l'aide de la programmation d'agent et d'une approche sans ressources.
  • Le chapitre 12 décrit la programmation d'agent à l'aide de la bibliothèque de flux de données TPL de .NET avec des exemples en C #. Il montre comment implémenter des agents sans état et avec état en C #, ainsi que comment effectuer plusieurs calculs en parallèle qui échangent des données entre eux, en utilisant (envoyant) des messages dans le style d'un pipeline.

La partie III montre comment mettre en pratique toutes les méthodes fonctionnelles de programmation compétitive étudiées dans les chapitres précédents.

  • Le chapitre 13 présente un ensemble de recettes utiles pour résoudre des problèmes de concurrence complexes, tirées de la pratique réelle. Ces recettes utilisent tous les modèles fonctionnels décrits dans ce livre.
  • Le chapitre 14 décrit une application à part entière développée et mise en œuvre à l'aide de modèles et de méthodes compétitifs fonctionnels étudiés dans ce livre. Vous allez créer une application serveur hautement évolutive et réactive et un programme client réactif. Le livre contient deux versions: une pour iOS (iPad), créée à l'aide de Xamarin Visual Studio, et la seconde - créée à l'aide de Windows Presentation Foundation (WPF). Pour garantir une évolutivité maximale dans l'application serveur, une combinaison de divers modèles de programmation, tels que asynchrone, agent et réactif, est utilisée.

Le livre contient également trois applications.

  • L'annexe A décrit brièvement les concepts de base de la programmation fonctionnelle et présente la théorie de base des méthodes fonctionnelles utilisées dans ce livre.
  • L'annexe B présente les concepts de base du langage F #. Il s'agit d'une revue de base de F #, qui vous permettra de vous familiariser avec cette langue et de vous sentir à l'aise lors de la lecture d'un livre.
  • L'annexe B illustre plusieurs méthodes qui simplifient l'interaction entre un flux de travail asynchrone en F # et une tâche .NET en C #.

Extrait. 11.6. F # MailboxProcessor: 10 000 agents pour Game of Life


Comparé aux threads, MailboxProcessor en combinaison avec des workflows asynchrones est une simple unité informatique (primitive). Les agents peuvent apparaître et être détruits à un coût minime. Vous pouvez répartir le travail entre plusieurs objets MailboxProcessor de la même manière que vous pouvez utiliser des threads, sans la surcharge supplémentaire associée à la création d'un nouveau thread. Grâce à cela, il est tout à fait possible de créer des applications composées de centaines de milliers d'agents travaillant en parallèle avec une charge minimale sur les ressources informatiques.

Dans cette section, nous utiliserons plusieurs instances de MailboxProcessor pour implémenter le jeu Game of Life (le jeu "Life") ( wiki-eng et wiki-eng ). Selon Wikipedia, le Game of Life, en termes simples, est un automate cellulaire. Il s'agit d'un jeu sans joueurs - en d'autres termes, lorsqu'un jeu démarre avec une configuration initiale aléatoire, il s'exécute sans aucune autre entrée. Le jeu consiste en un ensemble de cellules formant une grille; dans chaque cellule, plusieurs règles mathématiques sont remplies. Les cellules peuvent vivre, mourir et se multiplier. Chaque cellule interagit avec huit voisins (cellules voisines). Pour déplacer les cellules conformément à ces règles, il est nécessaire de calculer en permanence le nouvel état du maillage.

Game of Life a les règles suivantes:

  • si une cellule n'a qu'un seul voisin ou aucun voisin, alors elle meurt "de solitude";
  • si quatre voisins ou plus d'une cellule meurent, elle meurt «à cause de la surpopulation»;
  • si la cellule a deux ou trois voisins, elle reste à vivre;
  • si une cellule a trois voisins, elle se multiplie.

Selon les conditions initiales, les cellules forment des structures caractéristiques tout au long du jeu. Grâce à l'application répétée des règles, les générations de cellules suivantes sont créées jusqu'à ce que les cellules atteignent un état stable (Fig. 11.12).

Le Listing 11.9 montre l'implémentation de la cellule Game of Life AgentCell, basée sur les types F # de MailboxProcessor. Chaque cellule d'agent interagit avec les cellules voisines via une messagerie asynchrone, créant ainsi un jeu de vie entièrement parallélisé. Par souci de concision, j'ai omis certaines parties du code, car elles ne sont pas liées au sujet principal de l'exemple. Vous trouverez l'implémentation complète dans le code source de ce livre, publié sur le site Web de l'éditeur.

image

image

AgentCell décrit une cellule de la grille Game of Life. Le concept de base est que chaque agent échange des informations avec les cellules voisines sur son état actuel via la messagerie asynchrone. Ce modèle crée une chaîne de communications parallèles interconnectées qui implique que toutes les cellules envoient leur état mis à jour à l'agent de mise à jour MailboxProcessor. Après avoir reçu ces données, updateAgent met à jour les graphiques dans l'interface utilisateur (extrait 11.10).

image

image

updateAgent, comme son nom l'indique, met à jour l'état de chaque pixel en fonction de la valeur de cellule reçue dans le message de mise à jour. L'agent maintient l'état des pixels et l'utilise pour créer une nouvelle image lorsque toutes les cellules transmettent leur nouvel état. UpdateAgent met ensuite à jour l'interface graphique WPF en utilisant cette nouvelle image qui correspond à la grille Game of Life actuelle:

do! Async.SwitchToContext ctx image.Source <- createImage pixels do! Async.SwitchToThreadPool() 

Il est important de noter que le updateAgent utilise le contexte de synchronisation actuel pour mettre correctement à jour le contrôleur WPF. Le thread actuel est basculé vers le thread d'interface utilisateur à l'aide de la fonction Async.SwitchToContext (décrite au chapitre 9).

Le dernier morceau de code pour exécuter Game of Life génère une grille qui sert de terrain de jeu pour les cellules, puis le chronomètre informe les cellules de la nécessité d'effectuer une mise à jour (extrait 11.11). Dans cet exemple, la grille est un carré de 100 × 100 cellules, soit un total de 10 000 cellules (objets MailboxProcessor), qui sont calculées en parallèle avec un temporisateur toutes les 50 ms, comme le montre la Fig. 11.13. Dix mille objets MailboxProcessor interagissent et mettent à jour l'interface utilisateur 20 fois par seconde (le code auquel vous devez faire attention est affiché en gras).

image

image

Les notifications à toutes les cellules (agents) sont envoyées en parallèle à l'aide de PLINQ. Les cellules sont des séquences F # qui sont traitées comme .NET IEnumerable, ce qui facilite l'intégration de LINQ / PLINQ.

image

Lorsque le code est exécuté, le programme génère 10 000 objets F # de type MailboxProcessor en moins de 1 ms, tandis que les agents occupent moins de 25 Mo de mémoire. Impressionnant!

Résumé


  • Le modèle de programmation basé sur les agents offre naturellement l'immuabilité et l'isolement lors de l'écriture de systèmes concurrents, ce qui facilite encore plus la discussion sur les systèmes complexes, car les agents sont encapsulés dans des objets actifs.
  • Un manifeste réactif définit les propriétés de mise en œuvre d'un système réactif qui est flexible, faiblement couplé et évolutif.
  • L'isolement naturel est important pour écrire du code concurrentiel sans bloquer. Dans un programme multi-thread, l'isolement résout le problème des états partagés en fournissant à chaque thread une donnée copiée pour effectuer des calculs locaux. Lors de l'utilisation d'isolant, il n'y a pas de condition de concurrence.
  • Étant asynchrones, les agents sont simples car ils ne bloquent pas les threads en attendant les messages. Par conséquent, vous pouvez utiliser des centaines de milliers d'agents dans une seule application sans beaucoup d'impact sur la taille de la mémoire.
  • Un objet MailboxProcessor F # fournit une communication bidirectionnelle: un agent peut utiliser un canal asynchrone pour renvoyer (répondre) le résultat du calcul à l'objet appelant.
  • Le modèle de programmation d'agent en F # via MailboxProcessor est un excellent outil pour résoudre les goulots d'étranglement dans les applications, comme l'accès simultané à plusieurs bases de données. En fait, avec l'aide d'agents, vous pouvez accélérer considérablement l'application, tout en conservant la réactivité du serveur.
  • D'autres langages de programmation .NET vous permettent d'utiliser le MailboxProcessor de type F #, fournissant des méthodes utilisant le modèle de programmation TPL pratique basé sur les tâches.

»Plus d'informations sur le livre sont disponibles sur le site Web de l'éditeur
» Contenu
» Extrait

Coupon de 20% sur les colporteurs - Concurrence dans .NET

Lors du paiement de la version papier du livre, une version électronique du livre est envoyée par e-mail.

Source: https://habr.com/ru/post/fr453804/


All Articles