web-dev-qa-db-fra.com

Quelle est la différence entre le modèle événementiel et le modèle de réacteur?

Extrait du wikipedia Reactor Pattern article:

Le modèle de conception de réacteur est un modèle de gestion d'événements pour gérer les demandes de service délivrées simultanément à un gestionnaire de services par une ou plusieurs entrées.

Il a cité quelques exemples, par exemple nodejs, twisted, eventmachine

Mais ce que je comprends, c'est que ci-dessus est un cadre populaire basé sur les événements, alors faites-en également un cadre de modèle de réacteur?

Comment différencier ces deux? Ou ce sont les mêmes?

73
Howard

Le modèle de réacteur est plus spécifique que la "programmation événementielle". Il s'agit d'une technique d'implémentation spécifique utilisée lors de la programmation événementielle. Cependant, le terme n'est pas utilisé avec beaucoup de précision dans une conversation typique, vous devez donc faire attention à l'utiliser et vous attendre à ce que votre public vous comprenne, et vous devez être prudent dans la façon dont vous interprétez le terme lorsque vous rencontrez son utilisation.

Une façon d'examiner le modèle du réacteur est de le considérer comme étroitement lié à l'idée d'opérations "sans blocage". Le réacteur envoie des notifications lorsque certaines opérations peuvent être achevées sans blocage. Par exemple, select(2) peut être utilisé pour implémenter le modèle de réacteur pour la lecture et l'écriture sur les sockets en utilisant les API de socket BSD standard (recv(2), send(2), etc.) . select vous indiquera quand vous pouvez recevoir des octets d'un socket instantanément - parce que les octets sont présents dans le tampon du récepteur du noyau pour ce socket, par exemple.

Un autre modèle que vous voudrez peut-être considérer en réfléchissant à ces idées est le modèle proactif . Contrairement au modèle de réacteur, le modèle proactor a des opérations de démarrage, qu'elles puissent se terminer immédiatement ou non, les a effectuées de manière asynchrone , puis organise fournir une notification de leur achèvement.

L'API Windows I/O Completion Ports (IOCP) est un exemple où le modèle proactor peut être vu. Lorsque vous effectuez un envoi sur un socket avec IOCP, l'opération d'envoi est lancée, qu'il y ait ou non de la place dans le tampon d'envoi du noyau pour ce socket. L'opération d'envoi se poursuit (dans un autre thread, peut-être un thread dans le noyau) tandis que l'appel WSASend se termine immédiatement. Lorsque l'envoi se termine (ce qui signifie seulement que les octets envoyés ont été copiés dans le tampon d'envoi du noyau pour ce socket), une fonction de rappel fournie au WSASend l'appel est appelé (dans un nouveau thread dans l'application).

Cette approche consistant à démarrer des opérations et à être ensuite notifié lorsqu'elles sont terminées est au cœur de l'idée des opérations asynchrones . Comparez-le aux opérations non bloquantes où vous attendez qu'une opération puisse se terminer immédiatement avant de tenter de l'exécuter.

L'une ou l'autre approche peut être utilisée pour la programmation événementielle. En utilisant le modèle de réacteur, un programme attend l'événement de (par exemple) un socket lisible, puis lit à partir de celui-ci. En utilisant le modèle proactor, le programme attend à la place l'événement d'une lecture de socket terminée.

À proprement parler, Twisted abuse du terme réacteur . Le réacteur Twisted basé sur select(2) (twisted.internet.selectreactor) est implémenté à l'aide d'E/S non bloquantes, qui sont très semblables à des réacteurs. Cependant, l'interface qu'elle expose au code d'application est asynchrone , ce qui la rend plus proactive. Twisted possède également un réacteur basé sur l'IOCP. Ce réacteur expose la même API asynchrone orientée application et utilise les API IOCP de type proacteur. Cette approche hybride, variant de plateforme en plateforme dans ses détails, ne rend ni le terme "réacteur" ni "proacteur" particulièrement précis, mais depuis l'API exposée par twisted.internet.reactor est fondamentalement entièrement asynchrone au lieu de non bloquant, proactor aurait probablement été un meilleur choix de nom.

125
Jean-Paul Calderone

Je pense que cette séparation "non bloquante" et "asynchrone" est erronée, car l'implication principale de "asynchrone" est "non bloquante". Le modèle de réacteur concerne les appels asynchrones (donc non bloquants), mais le traitement synchrone (bloquant) de ces appels. Proactor concerne les appels asynchrones (non bloquants) et le traitement asynchrone (non bloquant) de ces appels.

6
emanuel

Pour gérer les connexions TCP, il existe deux architectures Web concurrentes, à savoir l'architecture basée sur les threads et l'architecture pilotée par les événements.

Architecture basée sur les threads

La manière la plus ancienne d'implémenter un serveur multithread suit l'approche "thread par connexion". Afin de contrôler et de limiter le nombre de threads en cours d'exécution, un seul thread de dispatcher peut être utilisé avec une file d'attente de blocage bornée et un pool de threads.

Le répartiteur bloque sur une socket TCP pour les nouvelles connexions et les propose à la file d'attente de blocage bornée. TCP les connexions dépassant la limite de la file d'attente seront abandonnées, connexions acceptées pour fonctionner avec une latence souhaitable et prévisible.

Architecture événementielle

Séparant les threads des connexions, l'architecture basée sur les événements permet uniquement aux threads d'être utilisés pour les événements sur des gestionnaires spécifiques.

Ce concept créatif permet à Reactor Pattern de sortir de l'étagère et de se montrer. Un système construit sur cette architecture est composé de créateurs d'événements et de consommateurs d'événements.

Le modèle de réacteur

Le modèle de réacteur est la technique d'implémentation la plus populaire de l'architecture pilotée par les événements pour la gestion des connexions TCP. En termes simples, il utilise une boucle d'événements à thread unique, bloquant les événements et distribuant ces événements aux événements correspondants gestionnaires.

Il n'est pas nécessaire que d'autres threads se bloquent sur les E/S, tant que les gestionnaires d'événements sont enregistrés pour s'en occuper. En considérant une connexion TCP, nous pouvons facilement référencer des événements à ces instances: connecté, prêt pour l'entrée, prêt pour la sortie, délai d'expiration et déconnecté.

Le modèle de réacteur dissocie le code modulaire au niveau de l'application de la mise en œuvre réutilisable du réacteur. Pour y parvenir, l'architecture du modèle de réacteur se compose de deux participants importants: le réacteur et les gestionnaires.

Réacteur

Un réacteur s'exécute dans un thread séparé et réagit aux événements d'E/S tels que connecté, prêt à l'entrée, prêt à la sortie, délai d'expiration et déconnecté, en envoyant le travail au gestionnaire enregistré approprié.

Gestionnaires

Un gestionnaire effectue le travail réel ou la réponse qui doit être effectuée avec un événement d'E/S. Un réacteur répond aux événements d'E/S en envoyant le gestionnaire approprié.

"Pattern Languages ​​of Program Design" de Jim Coplien et Douglas C. Schmidt, publié en 1995, est l'un des livres qui a expliqué en détail le modèle de réacteur.

1
Yasas Gunarathne