Threads vs Async

Je lisais sur le modèle filaire de programmation par rapport au modèle asynchrone de ce très bon article. http://krondo.com/blog/?p=1209

Cependant, l’article mentionne les points suivants.

  1. Un programme asynchrone surpasse simplement un programme de synchronisation en basculant entre les tâches chaque fois qu’il ya une E / S.
  2. Les threads sont gérés par le système d’exploitation.

Je me rappelle avoir lu que les threads sont gérés par le système d’exploitation en se déplaçant autour des TCB entre la queue prête et la queue d’attente (parmi d’autres files d’attente). Dans ce cas, les threads ne perdent pas de temps à attendre non plus, n’est-ce pas?

À la lumière de ce qui précède, quels sont les avantages des programmes asynchrones par rapport aux programmes threadés?

  1. Il est très difficile d’écrire du code qui est thread-safe. Avec un code asynchrone, vous savez exactement où le code passera d’une tâche à l’autre et les conditions de course sont donc beaucoup plus difficiles à trouver.
  2. Les threads consumnt pas mal de données car chaque thread doit avoir sa propre stack. Avec le code asynchrone, tout le code partage la même stack et la stack est réduite en raison du déroulement continu de la stack entre les tâches.
  3. Les threads sont des structures de système d’exploitation et offrent donc davantage de mémoire pour la plate-forme. Il n’y a pas un tel problème avec les tâches asynchrones.

Il existe deux manières de créer des threads:

threading synchrone – le parent crée un (ou plusieurs) threads enfant et doit ensuite attendre que chaque enfant se termine. Le threading synchrone est souvent appelé le modèle fork-join .

threading asynchrone – le parent et l’enfant s’exécutent simultanément / indépendamment l’un de l’autre. Les serveurs multithread suivent généralement ce modèle.

ressource – http://www.amazon.com/Operating-System-Concepts-Abraham-Silberschatz/dp/0470128720

Tout d’abord, notez qu’une grande partie du détail de la mise en œuvre et de la planification des threads est très spécifique au système d’exploitation. En général, vous ne devriez pas avoir à vous soucier des threads qui s’attendent les uns les autres, car le système d’exploitation et le matériel essaieront de les faire fonctionner efficacement, de manière asynchrone sur un système monoprocesseur ou en parallèle sur des processeurs multiples.

Une fois qu’un thread a fini d’attendre quelque chose, disons I / O, il peut être considéré comme exécutable. Les threads exécutables seront bientôt exécutés. Que cela soit implémenté sous la forme d’une simple queue ou de quelque chose de plus sophistiqué, là encore, le système d’exploitation et le matériel sont spécifiques. Vous pouvez considérer l’ensemble des threads bloqués comme un ensemble plutôt qu’une queue ssortingctement ordonnée.

Notez que sur un système monoprocesseur, les programmes asynchrones tels que définis ici sont équivalents aux programmes threadés.

  1. Supposons que vous ayez 2 tâches, qui n’impliquent aucune IO (sur un ordinateur multiprocesseur). Dans ce cas, les threads surpassent les Async. Comme Async comme un seul programme thread exécute vos tâches dans l’ordre. Mais les threads peuvent exécuter les deux tâches simultanément.

  2. Supposons que vous ayez 2 tâches impliquant IO (sur un ordinateur multiprocesseur). Dans ce cas, les fonctions Async et Threads sont plus ou moins identiques (les performances peuvent varier en fonction du nombre de cœurs, de la planification, de l’intensité du processus, etc.). Async prend également moins de ressources, moins de frais généraux et moins complexe à programmer sur des programmes multithread.

Comment ça marche? Le thread 1 exécute la tâche 1, car il attend IO, il est déplacé dans la queue d’attente IO. De même, le thread 2 exécute la tâche 2, car il implique également IO, il est déplacé vers la queue d’attente IO. Dès que sa requête IO est résolue, elle est déplacée dans la queue afin que le planificateur puisse planifier l’exécution du thread.

Async exécute la tâche 1 et, sans attendre la fin des opérations IO, elle continue avec la tâche 2, puis attend la fin des opérations IO. Il complète les tâches dans l’ordre d’achèvement des entrées / sorties.

Async mieux adapté aux tâches impliquant des appels de service Web, des appels de requête de firebase database, etc.

La vidéo ci-dessous explique le Async vs Threaded model ainsi que l’utilisation, etc., https://www.youtube.com/watch?v=kdzL3r-yJZY

J’espère que c’est utile.

Async I / O signifie qu’il existe déjà un thread dans le pilote qui effectue le travail. Vous dupliquez donc les fonctionnalités et indiquez des frais supplémentaires. D’un autre côté, il n’est souvent pas documenté comment se comporte exactement le thread de pilote, et dans des scénarios complexes, lorsque vous souhaitez contrôler le comportement timeout / cancel / start / stop, la synchronisation avec d’autres threads, il est logique d’implémenter votre propre thread. Il est également parfois plus facile de raisonner en termes de synchronisation.

voir http://en.wikipedia.org/wiki/Thread_(computing)#I.2FO_and_scheduling

Cependant, l’utilisation d’appels système bloquants dans les threads utilisateur (par opposition aux threads du kernel) ou de fibres peut poser problème. Si un thread utilisateur ou une fibre exécute un appel système qui se bloque, les autres threads utilisateur et fibres du processus ne peuvent pas s’exécuter tant que l’appel système ne sera pas renvoyé. Un exemple typique de ce problème est la réalisation d’E / S: la plupart des programmes sont écrits pour effectuer des E / S de manière synchrone. Lorsqu’une opération d’E / S est lancée, un appel système est effectué et ne revient pas tant que l’opération d’E / S n’est pas terminée. Dans l’intervalle, l’ensemble du processus est “bloqué” par le kernel et ne peut pas être exécuté, ce qui empêche d’autres threads et fibres utilisateur de s’exécuter dans le même processus.

En conséquence, tout votre processus peut être bloqué et aucun thread ne sera planifié lorsqu’un thread est bloqué dans IO. Je pense que cela est spécifique à l’os et ne sera pas toujours valable.