Quelle est la différence entre: des architectures asynchrones, non-bloquantes, basées sur des événements?
-
Quelle est la différence entre:
- asynchrone ,
- Non-Blocking , et
- Cas de base architectures?
-
quelque chose Peut être à la fois asynchrone et non bloquant (et basé sur des événements )?
-
Qu'est-ce qui est le plus important dans la programmation, d'avoir quelque chose: asynchrone, non-bloquant et/ou événement-base (ou tous les 3)?
Si vous pouviez donner des exemples, ce serait génial.
cette question est posée parce que je lisais ce grand StackOverflow article sur un sujet similaire, mais il ne répond pas à mes questions ci-dessus.
5 réponses
asynchrone Asynchrone signifie littéralement pas synchrone. Le courriel est asynchrone. Vous envoyez un mail, vous ne vous attendez pas à recevoir une réponse maintenant. Mais il n'est pas non bloquant. Essentiellement, il s'agit d'une architecture où les "composants" envoient des messages les uns aux autres sans attendre de réponse immédiate. Les requêtes HTTP sont synchrones. Envoyez une demande et obtenez une réponse.
Non Bloquant Ce terme est surtout utilisé avec IO. Ce que cela signifie est que lorsque vous faites un appel système, il reviendra immédiatement avec n'importe quel résultat qu'il a sans mettre votre fil à dormir (avec une forte probabilité). Par exemple, les appels en lecture/écriture non bloquants reviennent avec tout ce qu'ils peuvent faire et s'attendent à ce que l'appelant exécute de nouveau l'appel. try_lock par exemple est un appel non-bloquant. Il se verrouille seulement si la serrure peut être acquise. La sémantique habituelle pour les appels systèmes bloque. lire attendra jusqu'à ce qu'il ait quelques données et mettre le thread d'appel à dormir.
Cas de base Ce terme vient de libevent. les appels non bloquants en lecture / écriture sont inutiles parce qu'ils ne vous disent pas "quand" si vous les rappelez (réessayez). select / epoll / IOCompletionPort etc sont des mécanismes différents pour trouver à partir de OS "quand" ces appels sont censés retourner des données "intéressantes". libevent et d'autres bibliothèques de ce type offrent des services de veille d'événements fournis par divers Oss et donnez une API cohérente à travailler avec laquelle fonctionne l'ensemble des systèmes d'exploitation. IO Non-bloquant va de pair avec Event-base.
je pense que ces termes se chevauchent. Par exemple, le protocole HTTP est synchrone, mais L'implémentation HTTP utilisant IO non-bloquant peut être asynchrone. Encore une fois, un appel API non-bloquant comme read/write/try_lock est synchrone (il donne immédiatement une réponse) mais la "manipulation des données" est asynchrone.
Dans asynchrone matériel, code demande à une entité de faire quelque chose et est libre de faire d'autres choses pendant que l'action se fait; une fois l'action terminée, l'entité sera généralement le signal de code d'une certaine façon. Une architecture non-bloquante prendra note des actions spontanées qui pourraient intéresser le code, et permettra à celui-ci de demander ce que de telles actions ont eu lieu, mais le code ne sera conscient de ces actions que s'il les demande explicitement. Une approche basée sur les événements l'architecture avertira le code lorsque des événements se produisent spontanément.
Considérer un port série, à partir de laquelle le code voulez recevoir 1 000 octets.
dans une architecture de blocage-lecture, le code attendra jusqu'à ce que 1.000 octets soient arrivés ou qu'il décide d'abandonner.
dans une architecture à lecture asynchrone, le code indiquera au pilote qu'il veut 1.000 octets, et sera notifié lorsque 1.000 octets sont arrivés.
dans une architecture non-bloquante, le code peut demander à tout moment combien d'octets sont arrivés, et peut lire n'importe quelle ou toutes ces données quand il le juge approprié, mais la seule façon qu'il peut savoir quand toutes les données sont arrivées est de demander; si le code veut savoir dans un quart de seconde quand le 1000ème octet est arrivé, il doit vérifier chaque quart de seconde ou ainsi.
dans une architecture basée sur un événement, le pilote du port série avertira l'application à tout moment arriver. Le pilote ne saura pas combien d'octets l'application veut, donc l'application doit être capable de traiter les notifications pour des montants qui sont plus petits ou plus grands que ce que l'application veut.
pour moi, le non-blocage signifie que l'exécution d'une action dans un thread ne dépend pas de l'exécution d'autres threads, il ne nécessite en particulier pas de section critiale.
signifie asynchrone que l'exécution se produit en dehors du flux de l'appelant, et est potentiellement diffractée. L'exécution se produit typiquement dans un autre thread.
la lecture de données simultanées est non-bloquante (pas besoin de verrouillage), mais synchrone. Inversément, en écrivant données simultanément une manière synchrone est bloquant (nécessite un verrou exclusif). Une façon de le rendre non-bloquant du point de vue du flux principal est de rendre les écritures asynchrones et de différer leur exécution.
le concept d'événement est autre chose, ce qui signifie en gros que vous êtes informé quand quelque chose se produit. Si les Écritures ont été exécutées de manière asynchrone, un événement peut être soulevé pour informer les autres parties du système une fois que l'écriture a été exécutée. Le d'autres pièces de répondre à l'événement. Système peut être construit uniquement sur les événements comme la seule façon de communiquer entre les composants (pensez au modèle de l'acteur), mais il ne doit pas être nécessaire d'être le cas.
Les trois termes sont liés, mais sont des concepts différents pour moi. Il peut être que les gens les utilisent dans un peu interchangeables manière.
en général, une architecture non-bloquante est basée sur des appels de méthode qui, bien qu'ils puissent s'exécuter longtemps sur le thread worker , ne bloquent pas le thread calling . Si le thread appelant a besoin d'acquérir des informations sur ou à partir de la tâche que le thread worker exécute, c'est au thread appelant de le faire.
une architecture basée sur les événements est basée sur le concept de code exécuté en réponse à les événements qui sont déclenchés. Le moment de l'exécution du code n'est généralement pas déterministe, mais les événements peuvent invoquer des méthodes de blocage; ce n'est pas parce qu'un système est basé sur des événements que tout ce qu'il fait ne bloque pas.
en général, une architecture asynchrone est une architecture non-bloquante basée sur des événements.
Quand un appel asynchrone est fait, les gestionnaires d'événements sont enregistrés auprès de l'API fournissant des services de synchronisation, afin d'aviser l'appelant que ce qui intéresse l'appelant est arrivé. L'appel puis retourne immédiatement (comportement non bloquant), et l'appelant est libre de continuer l'exécution. Lorsque des événements sont renvoyés au processus d'appel, ils seront traités sur un fil dans ce processus.
il est important de comprendre si les événements seront traités sur le même fil ou non, car cela affectera la nature non-bloquante de l'exécution, mais je ne suis pas personnellement au courant d'aucune les bibliothèques qui gèrent l'exécution asynchrone sur un seul thread.
j'ai supprimé le paragraphe ci-dessus parce qu'il n'est pas strictement correct comme indiqué. Mon intention était de dire que même si les opérations dans le système ne sont pas bloquants, tels que faire des appels à une installation de système D'exploitation et l'exécution continue, la nature de l'exécution monofiltre signifie que lorsque les événements sont déclenchés, ils seront en concurrence avec d'autres tâches de traitement pour calculer le temps sur le fil.
donc pour répondre à votre première et deuxième question:
Non-blocage est effectivement la même chose que asynchrone - vous faites l'appel, et vous obtiendrez un résultat plus tard, mais pendant que cela se produit, vous pouvez faire autre chose. Le blocage est à l'opposé. Vous attendez le retour de l'appel avant de poursuivre votre voyage.
maintenant le code Async/Non-blocking sonne absolument fantastique, et il l'est. Mais j'ai des mots de mise en garde. Async/Non bloquantes sont grands lorsque vous travaillez dans des environnements restreints, comme dans un téléphone mobile... considérez CPU / mémoire limitée. C'est aussi bon pour le développement frontal, où votre code doit réagir à un widget UI d'une façon ou d'une autre.
Async est fondamental à la façon dont tous les systèmes d'exploitation doivent fonctionner - ils obtiennent Merde fait pour vous dans l'arrière-plan et réveiller votre code quand ils ont fait ce que vous avez demandé, et quand cet appel échoue, on vous dit qu'il n'a pas fonctionné par une exception, ou une sorte de retourner le code / l'objet d'erreur.
au moment où votre code demande quelque chose qui prendra un certain temps à répondre, votre OS sait qu'il peut être occupé à faire d'autres choses. Votre code - un processus, un fil ou l'équivalent, bloque. Votre code est totalement inconscients de ce qui se passe dans l'OS pendant qu'il attend que la connexion au réseau doit être effectué, ou pendant qu'il attend la réponse d'une requête HTTP, ou pendant qu'il attend que lire/écrire un fichier, et ainsi de suite. Vous code peut "simplement" être en attente d'un clic de souris. Ce qui se passait réellement pendant cette période était que votre système d'exploitation gérait, planifiait et réagissait de façon transparente aux "événements" - des choses que le système d'exploitation recherche, comme la gestion de la mémoire, les e/s (Clavier, Souris). disque, internet), d'autres tâches, récupération d'échec, etc.
systèmes D'exploitation à noyau dur. Ils sont vraiment bons pour cacher tous les trucs compliqués async / non-blocage de vous le programmeur. Et c'est comment la plupart des programmeurs arrivés là où nous en sommes aujourd'hui avec un logiciel. Maintenant que nous atteignons les limites du CPU, les gens disent que des choses peuvent être faites en parallèle pour améliorer la performance. Cela signifie que Async / non-blocage semble être une chose très favorable à faire, et oui, si votre logiciel l'exige, je peux être d'accord.
si vous écrivez un serveur web d'arrière-plan, procédez avec prudence. Rappelez vous de l'échelle horizontale pour beaucoup moins cher. Netflix / Amazon / Google / Facebook sont évidents des exceptions à cette règle cependant, tout simplement parce qu'il s'avère moins coûteux pour eux d'utiliser moins de matériel.
je vais vous dire pourquoi le code async / non-blocking est un cauchemar avec les systèmes back-end....
1) il devient un déni de service sur la productivité... vous devez penser beaucoup plus, et vous faites beaucoup d'erreurs en cours de route.
2) les traces de pile en code réactif deviennent indéchiffrables - il est difficile de savoir ce qu'on appelle quoi, quand, pourquoi et comment le faire. Bonne chance pour le débogage.
3) vous devez réfléchir davantage sur la façon dont les choses échouent, en particulier quand beaucoup de choses reviennent hors de l'ordre de la façon dont vous les avez envoyées. Dans l'ancien monde, tu faisais une chose à la fois.
4) c'est plus difficile à tester.
5) c'est plus difficile à entretenir.
6) c'est douloureux. La programmation devrait être une joie et un plaisir. Seuls les masochistes aiment la douleur. Personnes qui rédigent des textes concurrents / réactifs les cadres sont des sadiques.
et oui, j'ai écrit sync et async. Je préfère synchrone car 99.99 des applications back-end peuvent se débrouiller avec ce paradigme. Les applications Front-end ont besoin de code réactif, sans aucun doute, et cela a toujours été le cas.
-
Oui, le code peut être asynchrone, non bloquant et basé sur l'événement.
-
la chose la plus importante dans la programmation est de s'assurer votre code fonctionne et répond dans un délai acceptable. Respecte ce principe clé et tu ne peux pas te tromper.