Pourquoi pas les fils verts?

33

Bien que je sache que des questions à ce sujet ont déjà été abordées (par exemple, https://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads ), je n'ai pas l'impression d'avoir une réponse satisfaisante. .

La question qui se pose est la suivante: pourquoi la machine virtuelle Java ne prend-elle plus en charge les threads verts?

Voici ce que dit la FAQ Java de style code :

Un thread vert fait référence à un mode de fonctionnement de la machine virtuelle Java (JVM) dans lequel tout le code est exécuté dans un seul thread du système d'exploitation.

Et ceci sur java.sun.com :

L'inconvénient est que l'utilisation de threads verts signifie que les threads système sous Linux ne sont pas exploités et que la machine virtuelle Java n'est pas évolutive lorsque des processeurs supplémentaires sont ajoutés.

Il me semble que la machine virtuelle Java pourrait avoir un pool de processus système égal au nombre de cœurs, puis exécuter des threads verts par dessus. Cela pourrait offrir de gros avantages lorsque vous avez un très grand nombre de threads qui bloquent souvent (principalement parce que les JVM actuelles limitent le nombre de threads).

Pensées?

Redjamjar
la source
5
Pour moi, la question semble: Pourquoi des fils verts? Pourquoi réintroduire le multithreading en l'émulant au niveau de la JVM via plusieurs processus? C'est apparemment très pénible et onéreux de ne pas gagner, à part permettre aux programmeurs d'être plus généreux avec les threads de frai (et je ne suis pas convaincu que ce soit un avantage).
4
Eh bien, il s’agit d’avoir un modèle de programmation simultané qui évolue. Actuellement, en Java, si vous souhaitez une évolutivité, vous passez à NIO avec votre propre pool de threads. Au moins, c'est ce que j'ai compris.
Redjamjar
3
La présence d'éléments tels que < akka.io >, qui prend en charge les threads légers, me fait également penser que c'est nécessaire. En fait, je viens de trouver une très bonne discussion ici < stackoverflow.com/questions/7458782/… >
redjamjar
2
@delnan Parce que le changement de contexte pour les threads natifs coûte. Les threads verts ont beaucoup moins de temps système pour les synchronisations de changement de contexte et interprocess. En outre, le nombre de threads verts est pratiquement illimité (il peut en atteindre des centaines de milliers sans trop de stress pour les processus de VM), tandis que le nombre de threads natifs est limité par la surcharge de système d'exploitation et de mémoire.
permeakra
Il a fallu beaucoup de temps avant que la machine virtuelle Java prenne en charge directement les threads natifs. Les fils verts étaient la solution intermédiaire jusque-là.
Thorbjørn Ravn Andersen

Réponses:

29

Je me souviens de la JVM abandonnant les threads verts et passant à des threads natifs. Cela s'explique par deux raisons simples: les threads verts sont franchement nuls et il était nécessaire de prendre en charge les processeurs multicœurs avec les efforts de développement limités disponibles chez Sun.

C'était une honte - les threads verts fournissent une bien meilleure abstraction, ce qui permet à la concurrence d'accès d'être un outil utile et non une pierre d'achoppement. Mais les fils verts ne sont d'aucune utilité si plusieurs obstacles ne peuvent être surmontés:

  • ils doivent utiliser tous les cœurs de processeur disponibles

  • le changement de contexte doit être bon marché

  • Les E / S peuvent bloquer tous les threads qui y sont engagés, mais pas les autres threads, et certainement pas tous les autres threads, ce qui était le cas dans certaines implémentations antérieures.

Je me suis souvent demandé pourquoi le multi-threading est si difficile en Java, mais cela devient de plus en plus clair: c'était en fin de compte le passage aux threads natifs, qui sont:

  • bon à utiliser tous les noyaux de cpu

  • bon à être vraiment concurrent, fournissant des entrées / sorties indépendantes, etc.

  • lent au changement de contexte (comparé aux meilleures implémentations de thread vert)

  • horriblement gourmand en mémoire, limitant ainsi le nombre maximum utilisable d'entre eux

  • une piètre abstraction pour toute base permettant d'exprimer le monde réel, ce qui est hautement concourant bien sûr.

De nos jours, les programmeurs consacrent beaucoup de temps à coder des E / S non bloquantes, des contrats à terme, etc. Il est dommage que nous n'ayons pas un meilleur niveau d'abstraction.

À titre de comparaison, à part Erlang, la nouvelle langue de Go fait un bon travail de grande concurrence. Le grand-père de tous reste Occam , un projet de recherche en cours.

Rick-777
la source
jusqu'où sommes-nous allés depuis le temps que vous avez posté: O
Dmitry
3
Hélas, la rouille est un autre langage qui a abandonné de meilleures abstractions de concurrence. Eux aussi ont décidé de passer des threads coopératifs aux threads natifs.
Rick-777
2
@ Rick-777 Rust est un niveau trop bas pour le faire.
Malcolm
15

Un seul processus simulant plusieurs threads pose de nombreux problèmes. L'un d'eux est que tous les faux fils stagnent sur n'importe quel défaut de page.

L’alternative que vous proposez, un pool de processus, présente des avantages et des inconvénients. Le plus gros avantage, l'isolement des "fils", ne vous mènerait vraiment pas beaucoup ici. Le gros inconvénient, l’extrême difficulté de mise en oeuvre et une synchronisation moins efficace, est le tueur face à la concurrence.

Cependant, je conviens qu'il existe certaines applications (pas Java) dans lesquelles un pool de processus que vous pourriez utiliser comme un pool de threads (mais avec plus d'isolation) serait une excellente chose. Les fils partagent à peu près tout. Avec les processus, vous pouvez choisir spécifiquement ce que vous souhaitez partager. À ma connaissance, personne n’a encore tenté de la mettre en œuvre.

David Schwartz
la source
Occam prétend offrir cela. C'était une langue importante dans les années 80, mais elle souffrait d'un manque de financement pour le développement et ne devint par conséquent qu'un créneau de recherche. Mais ses idées sur la concurrence sont aussi solides qu’elles étaient à l’époque et doivent encore être améliorées.
Rick-777
Si vous êtes "multi-thread" à la golang (ordonnancement de type "M: N"), théoriquement, un seul thread vert est bloqué par une erreur de page car les autres threads peuvent "prendre le relais" (autres threads verts) semble-t-il. .. softwareengineering.stackexchange.com/questions/222642/…
rogerdpack
13

Il n'y aura aucun avantage pour un code Java moyen. Java n'est pas Erlang et les programmeurs Java ne sont pas dans le même état d'esprit que les programmeurs Erlang. Le langage n'a jamais été conçu pour être utilisé de cette façon.

Si vous voulez la vraie légèreté du processus - utilisez Erlang et créez des milliers de threads communiquant via des messages. En Java, une douzaine de threads partagent une mémoire commune avec des mutex et des sémaphores. C'est juste un modèle de programmation différent, conçu pour un ensemble différent de problèmes.

SK-logic
la source
Donc, pour clarifier les choses, c’est une approche utile à Erlang. Et, en ignorant les problèmes de l'état d'esprit Java, cela pourrait-il réellement aider?
Redjamjar
1
@redjamjar, il est peu probable qu'il soit utile en Java, le langage lui-même n'est pas tout à fait adapté à un tel usage, et son principal (et unique) avantage - le vaste ensemble de bibliothèques prêtes à l'emploi - ne s'intégrera pas parfaitement à un tel étranger. approche de programmation.
SK-logic
Oui, si vous voulez ce modèle, utilisez simplement Erlang, ce sera un ordre de grandeur plus facile
Zachary K
1
Java! = JVM, en train de dire :)
Kamil Tomšík
1
@Bane, ces "avantages" n'existent que si vous n'avez rien à comparer
SK-logic