Dernièrement, j'ai pensé: comment implémentent plusieurs "threads" dans un seul thread? p>
Je veux dire, comment ils implémentent plusieurs morceaux de code de fonctionnement parallèles dans un seul fil? Comment ils enregistrent l'état du «thread», créez une interruption et passez la CPU à la suivante? P>
Je pense que les acteurs scala mettent en œuvre cela. Mais comment? P>
Ceci peut être répondu pour JVM ou C, peu importe. Je veux vraiment vraiment apprendre la théorie de celle-ci. P>
6 Réponses :
Un moyen de faire cela consiste à faire enregistrer le package de threading dans le code d'utilisateur pour une sorte d'interruption de minuterie du noyau. Chaque fois qu'il reçoit une telle interruption, il peut dire au noyau d'arrêter l'exécution de tous les fils du noyau qui exécutent eux-mêmes plusieurs threads différents. Pour chacun de ces threads, le code d'interruption de la minuterie peut inspecter la pile pour ces threads, enregistrer des informations importantes (registres, pointeur de pile, compteur de programme, etc.) dans un emplacement auxiliaire, puis chargez les informations stockées pour un autre de la simulation. des fils fonctionnant sur ce fil réel. Il peut alors reprendre le fil du noyau exécutant le fil simulé. De cette manière, vous pouvez simuler la commutation de contexte entre les threads multiples fonctionnant sur un seul fil de noyau. P>
Pour mettre en œuvre quelque chose comme le verrouillage, vous pouvez garder une trace de toutes les informations de verrouillage localement dans votre espace utilisateur. Chaque fois qu'un fil simulé tente d'acquérir une serrure, vous pouvez vérifier si le thread peut obtenir avec succès la serrure. Si c'est le cas, vous vous donnez juste la serrure. Sinon, vous simulez un commutateur de contexte en échantillonnant ce que le thread simulé est en cours d'exécution sur ce fil réel, puis marquage du fil simulé comme bloqué jusqu'à ce que le verrou devienne à nouveau libre. P>
Ceci est juste un début - il y a beaucoup d'autres détails ici (que si l'un des threads simulés essaie de faire une opération d'E / S bloquant? Vous ne pouvez pas simplement bloquer le fil du noyau, car cela arrête de tous les threads simulés!), mais c'est le gist de l'idée. p>
Voulez-vous dire comme des tâches dans un service d'exécution ou une planchedexecutetorsservice en Java? P>
Ces tâches sont ajoutées à une file d'attente et préformées à l'achèvement. Quand on se termine qu'un autre commence. Si vous avez une boucle avec un délai, vous pouvez utiliser une tâche planifiée répétée. Il complète pour chaque itération et permet aux autres tâches de fonctionner. P>
Si vous voulez savoir plus de détails, vous trouverez peut-être lire le code intéressant. P>
@Jose Leal, tu veux dire comme des fils? Lorsque vous avez des tâches de poids légèrement dans un pool de filetage / filetage et de fils pouvant partager une CPU déjà, que feraient des threads à l'intérieur d'un fil vous gagnant?
Utilisez Coroutines P>
Je pense que la question est plus sur la manière dont vous pouvez mettre en œuvre une multithreading préemptive de n threads sur 1 fil de noyau.
Je pense que vous êtes confus Coroutines et threads verts ici. P>
Les Coroutines abandonnent le contrôle lorsqu'ils sont prêts à le faire, sans aucune interruption, la question de l'interruption n'est pas pertinente ici. Les acteurs scala sont mis en œuvre sous forme de coroutines. P>
Les threads verts sont des threads de mode utilisateur implémenté par la machine virtuelle sans utilisation de capacités de système d'exploitation natif. De toute évidence, la machine virtuelle peut insérer des instructions dans le code exécuté afin de vérifier si elle doit basculer vers un autre fil. P>
avec acteurs, il est simple, au lieu d'utiliser un fil par acteur, vous utilisez le même thread pour exécuter des messages pour plusieurs acteurs. Toutefois, si un acteur effectue un appel de blocage ou un calcul lourd, un autre thread doit être utilisé pour exécuter des messages dans d'autres acteurs. P>
Les threads verts sont des fils de poids légers pouvant être mis en œuvre au niveau VM. Les filets verts sont toujours mappés sur une ou plusieurs filets d'exploitation. La synchronisation et la commutation de thread sont traitées dans l'espace utilisateur par la machine virtuelle, ce qui peut réduire considérablement les frais généraux. Cependant, il y a des inconvénients sur des filets verts, par exemple les appels IO pourraient entraîner une blocage du fil, puis la machine virtuelle ne peut pas "réutiliser" le fil d'exploitation pour un autre fil vert et doit plutôt utiliser un fil d'exploitation supplémentaire. P>
Une autre solution consiste à utiliser des continuations, comme implémentées dans le compilateur Scala. L'interruption et la reprise de l'exécution sont ensuite traitées au niveau de la bytecode JVM où l'état local est enregistré et restauré. Aucun support VM n'est nécessaire. P>
Le bibliothèque AKKA est une très belle mise en œuvre du modèle des acteurs. Il a une assez bonne API Java droite (en plus de Scala One) et Le doc est plutôt bon . P>