299 votes

A-t-il rubis véritable multithreading ?

Je sais pas pour le filetage de la « coopérative » de ruby en utilisant les fils verts. Comment puis-je créer des vrais fils de « Niveau de l’OS » dans ma demande afin de faire usage de plusieurs cœurs de processeur pour le traitement ?

615voto

Jörg W Mittag Points 153275

Mis à jour avec de Jörg Sept 2011 commentaire

Vous semblez être déroutant deux très différentes choses ici: la Langage de Programmation Ruby et le modèle de thread de l'un mise en œuvre spécifique du Langage de Programmation Ruby. Il y sont actuellement de l'ordre de 11 différentes implémentations du Ruby Langage de programmation, avec de très différent et unique threading modèles.

(Malheureusement, seulement deux de ces 11 implémentations sont en fait prêt pour une utilisation en production, mais par la fin de l'année, ce nombre sera probablement aller jusqu'à quatre ou cinq.) (Mise à jour: il est maintenant 5: IRM, JRuby, YARV (l'interpréteur Ruby 1.9), Rubinius et IronRuby).

  1. La première mise en œuvre n'est pas réellement un nom, qui le rend assez difficile à se référer à elle et c'est vraiment ennuyeux et source de confusion. Il est le plus souvent désigné comme "Ruby", ce qui est encore de plus ennuyeux et de confusion que de ne pas avoir de nom, parce qu'il conduit à d'interminables confusion entre les fonctions de l'Ruby Langage de programmation et un Rubis particulière de mise en Œuvre.

    Elle est aussi parfois appelée "IRM" (pour "Matz Ruby La mise en œuvre"), CRuby ou MatzRuby.

    L'IRM met en œuvre Ruby Fils en tant que Fils Verts à l'intérieur de son interprète. Malheureusement, il ne permet pas à ceux des threads pour être programmée en parallèle, ils ne peuvent exécuter un thread à un temps.

    Cependant, un certain nombre de Fils C (POSIX Threads, etc.) pouvez l'exécuter en parallèle à la Ruby Thread, donc C externe Bibliothèques, ou IRM C Extensions de créer des threads de leur propre peut toujours s'exécuter en en parallèle.

  2. La deuxième application est YARV (abréviation de "Encore Un autre Rubis VM"). YARV implémente Ruby Threads comme POSIX ou Windows NT Fils, cependant, il utilise un Mondial Interprète De verrouillage (GIL) pour s'assurer qu'un seul Ruby Thread peut effectivement être prévu à la fois.

    Comme l'IRM, C Threads peuvent réellement fonctionner en parallèle à Ruby Threads.

    Dans l'avenir, il est possible, que le GIL peut obtenir cassé plus fine des serrures, permettant ainsi à plus de et plus code pour exécuter en parallèle, mais qui est si loin, il est même pas prévu encore.

  3. JRuby implémente Ruby Threads que les Threads Natifs, où les "Threads Natifs" dans le cas de la JVM, c'est évidemment "de la JVM Fils". JRuby impose pas de verrouillage complémentaire sur eux. Donc, si ces threads peut s'exécuter en parallèle dépend la JVM: certaines machines virtuelles en œuvre de la JVM des Threads comme OS de Threads et de certains en tant que Fils Verts.

  4. XRuby aussi implémente Ruby Threads comme JVM Threads. Mise à jour: XRuby est mort.

  5. IronRuby implémente Ruby Threads que les Threads Natifs, où les "Threads Natifs" dans le cas de la CLR signifie évidemment "CLR Fils". IronRuby impose pas de verrouillage supplémentaire sur eux, alors, ils doivent s'exécuter en parallèle, aussi longtemps que votre CLR prend en charge qu'.

  6. Ruby.NET aussi met en œuvre Ruby Threads comme CLR Les Threads. Mise À Jour: Ruby.NET est mort.

  7. Rubinius implémente Ruby Fils en tant que Fils Verts à l'intérieur de sa Machine Virtuelle. Plus précisément: le Rubinius VM exportations d'un très léger, très souple la simultanéité/parallélisme/non-local de contrôle des flux de construire, appelé une "Tâche", et tous les autres de la simultanéité des constructions (les Threads cette discussion, mais aussi les Continuations, les Acteurs et d'autres choses) sont mis en œuvre dans le plus pur Rubis, à l'aide de Tâches.

    Rubinius ne peut pas (encore) de l'annexe de Threads en parallèle, cependant, l'ajout qui n'est pas trop un problème: Rubinius peut déjà tourner plusieurs VM cas dans plusieurs Threads POSIX dans en parallèle, dans un délai d'un Rubinius processus. Etant donné que les Threads sont effectivement mises en Ruby, ils peuvent, comme tous les autres Ruby objet, être sérialisé et envoyée à une autre machine virtuelle dans un autre POSIX Thread. (C'est le même modèle que le FAISCEAU Erlang VM utilise pour SMP simultanéité. Il est déjà mis en œuvre pour Rubinius Acteurs.)

    Mise à jour: Les informations sur Rubinius dans cette réponse, c'est sur le Fusil à pompe VM, qui n'existe plus. La "nouvelle" C++ VM ne pas utiliser de fils verts prévue à travers plusieurs machines virtuelles (c'est à dire Erlang/FAISCEAU de style), il utilise une approche plus traditionnelle de machine virtuelle avec plusieurs système d'exploitation natif des threads modèle, tout comme celui utilisé par, disons, le CLR, Mono, et à peu près tous de la JVM.

  8. MacRuby a commencé comme un port de YARV sur le dessus de la Objective-C Runtime et CoreFoundation de Cacao et de Cadres. Il a maintenant considérablement divergé à partir de YARV, mais autant que je sache il actuellement encore partage le même Modèle de thread avec YARV. Mise à jour: MacRuby dépend de pommes garbage collector qui est déclarée obsolète et sera supprimée dans les versions ultérieures de MacOSX, MacRuby est morts-vivants.

  9. Le Cardinal est un Rubis de mise en Œuvre pour le Parrot La Machine Virtuelle. Il n'a pas d'implémenter les threads encore, cependant, quand il le fait, il sera probablement de les mettre en œuvre, Parrot Les Threads.

  10. MagLev est un Rubis de mise en Œuvre de la pierre précieuse/S Smalltalk VM. Je n'ai pas d'informations à ce modèle de thread Pierres précieuses/S utilise, ce modèle de thread MagLev utilise ou même si les fils sont même encore mis en œuvre (probablement pas).

  11. HotRuby est pas complète Rubis mise en Œuvre de ses propre. C'est une mise en œuvre d'un YARV bytecode de la VM en Le JavaScript. HotRuby ne prend pas en charge les threads (encore?) et quand il n', ils ne seront pas en mesure d'exécuter en parallèle, parce que JavaScript n'a pas de support pour de vrai parallélisme. Il y a un code ActionScript la version de HotRuby, cependant, et ActionScript pourrait en fait support de parallélisme. Mise à jour: HotRuby est mort.

Malheureusement, seulement deux de ces 11 Ruby Implémentations sont en fait prêt à la production: l'IRM et JRuby.

Donc, si vous voulez un vrai fils parallèles, JRuby est actuellement votre seul choix – pas que c'est une mauvaise: JRuby est effectivement plus rapide que l'IRM, et sans doute plus stable.

Sinon, le "classique" Ruby solution est d'utiliser les processus de au lieu de threads pour le parallélisme. La Librairie Principale contient l' Process module avec l' Process.fork la méthode qui en fait mort facile à fourche d'un autre Rubis processus. Aussi, le Rubis de la Bibliothèque Standard contient les Distribué Ruby (dRuby / dRb) de la bibliothèque, ce qui permet de Ruby code pour être trivialement distribué entre plusieurs processus, de ne pas que sur la même machine, mais aussi à travers le réseau.

28voto

Josh Moore Points 4363

Ruby 1.8 a seulement fils verts, il n’y a aucune méthode pour créer un véritable thread » au niveau du système d’exploitation ». Mais ruby 1.9 aura une nouvelle fonctionnalité appelée fibres, qui vous permettra de créer des threads au niveau du système d’exploitation réels. Ruby 1.9 est malheureusement, encore en version bêta, il est programmé pour être stable en quelques mois.

Une autre alternative consiste à utiliser de JRuby. JRuby implémente threads comme fil de niveau de l’OS, il n’y a aucun « fils verts » en elle. La dernière version de JRuby est 1.1.4 et équivaut à Ruby 1.8

8voto

user454322 Points 1172

Si vous voulez un vrai parallélisme en Ruby je vous recommande MacRuby ou JRubuy.
Ruby a des fermetures comme Blocks, lambdas et Procs. Pour profiter pleinement de fermetures et de plusieurs cœurs en JRuby, Java exécuteurs venir dans maniable; pour MacRuby j'aime PGCD de files d'attente.

Notez que, être capable de créer de véritables "OS" au niveau des threads ne signifie pas que vous pouvez utiliser plusieurs cœurs de processeur pour le traitement en parallèle. Regardez les exemples ci-dessous.

C'est la sortie d' un simple Ruby programme qui l'utilise 3 fils à l'aide de Ruby 2.1.0:

(jalcazar@mac ~)$ ps -M 69877
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 69877 s002    0.0 S    31T   0:00.01   0:00.04 /Users/jalcazar/.rvm/rubies/ruby-2.1.0/bin/ruby threads.rb
   69877         0.0 S    31T   0:00.01   0:00.00 
   69877        33.4 S    31T   0:00.01   0:08.73 
   69877        43.1 S    31T   0:00.01   0:08.73 
   69877        22.8 R    31T   0:00.01   0:08.65 

Comme vous pouvez le voir ici, il y a quatre OS threads, mais seulement l'un avec l'état R est en cours d'exécution. Cela est dû à une limitation dans la façon dont les Rubis, les threads sont mis en œuvre.



Même programme, maintenant avec JRuby. Vous pouvez voir les trois fils d'état R, ce qui signifie qu'ils sont exécutés en parallèle.

(jalcazar@mac ~)$ ps -M 72286
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 72286 s002    0.0 S    31T   0:00.01   0:00.01 /Library/Java/JavaVirtualMachines/jdk1.7.0_25.jdk/Contents/Home/bin/java -Djdk.home= -Djruby.home=/Users/jalcazar/.rvm/rubies/jruby-1.7.10 -Djruby.script=jruby -Djruby.shell=/bin/sh -Djffi.boot.library.path=/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jni:/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jni/Darwin -Xss2048k -Dsun.java.command=org.jruby.Main -cp  -Xbootclasspath/a:/Users/jalcazar/.rvm/rubies/jruby-1.7.10/lib/jruby.jar -Xmx1924M -XX:PermSize=992m -Dfile.encoding=UTF-8 org/jruby/Main threads.rb
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    33T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.09   0:02.34 
   72286         7.9 S    31T   0:00.15   0:04.63 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.04   0:01.68 
   72286         0.0 S    31T   0:00.03   0:01.54 
   72286         0.0 S    31T   0:00.00   0:00.00 
   72286         0.0 S    31T   0:00.01   0:00.01 
   72286         0.0 S    31T   0:00.00   0:00.01 
   72286         0.0 S    31T   0:00.00   0:00.03 
   72286        74.2 R    31T   0:09.21   0:37.73 
   72286        72.4 R    31T   0:09.24   0:37.71 
   72286        74.7 R    31T   0:09.24   0:37.80 


Le même programme, maintenant avec MacRuby. Il y a également trois threads s'exécutant en parallèle. C'est parce que MacRuby threads POSIX threads (réel "OS" au niveau de threads) et il n'y a pas de GVL

(jalcazar@mac ~)$ ps -M 38293
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 38293 s002    0.0 R     0T   0:00.02   0:00.10 /Users/jalcazar/.rvm/rubies/macruby-0.12/usr/bin/macruby threads.rb
   38293         0.0 S    33T   0:00.00   0:00.00 
   38293       100.0 R    31T   0:00.04   0:21.92 
   38293       100.0 R    31T   0:00.04   0:21.95 
   38293       100.0 R    31T   0:00.04   0:21.99 


Encore une fois, le même programme, mais maintenant avec le bon vieux RMI. En raison du fait que cette application utilise le vert-fils, un seul thread affiche

(jalcazar@mac ~)$ ps -M 70032
USER     PID   TT   %CPU STAT PRI     STIME     UTIME COMMAND
jalcazar 70032 s002  100.0 R    31T   0:00.08   0:26.62 /Users/jalcazar/.rvm/rubies/ruby-1.8.7-p374/bin/ruby threads.rb



Si vous êtes intéressé par Ruby le multi-threading, vous pourriez trouver mon rapport Activation des fonctionnalités de débogage de programmes parallèles l'aide d'une fourchette gestionnaires d' intéressant.
De plus pour un aperçu général de l'Ruby internes Ruby Sous un Microscope est un bon endroit pour chercher.

4voto

ujh Points 1722

Que diriez-vous à l’aide de drb? Il n’est pas vrai multi-threading mais la communication entre plusieurs processus, mais vous pouvez l’utiliser maintenant à 1,8 et c’est assez faible friction.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X