18

J'ai piraté Ruby de temps en temps, mais je n'ai rien fait de très gros ou de multithread avec. J'ai entendu que l'IRM prend uniquement en charge les threads verts et JRuby prend en charge les threads natifs via JVM. Cependant, je tombe sur des commentaires sur des blogs et des groupes de discussion qui disent que "Rails n'est pas thread-safe" ou que Ruby lui-même n'est pas thread safe. Par exemple, quelqu'un a commenté qu'il y avait un problème avec l'instruction require. Cela semble un peu fondamental.Sécurité du fil Ruby/Rails

J'ai vu beaucoup d'applications Java qui ne gèrent pas correctement et je concurrency des cauchemars de temps en temps :-) Mais au moins vous pouvez écrire des applications thread-safe en Java si vous vraiment sais ce que vous faites (ce n'est pas facile).

Tout cela semble très alarmant, quelqu'un peut élaborer plus - quel est exactement le problème et comment Rails parvient à travailler du tout si c'est le cas? Puis-je écrire du code Ruby multithread qui fonctionne correctement sans conditions de course et deadlocks? Est-il portable entre JRuby et MRI ou dois-je pirater du code spécifique JVM pour tirer parti des threads natifs JVM correctement?

EDIT:

j'aurais posé deux questions, parce que les gens ne semblent répondre aux rails des trucs de filetage (ce qui est bien en soi) et le filetage vert par rapport à filetage natif. Mes préoccupations sur les questions Ruby core sur le fil sécurité n'ont pas vraiment été abordées. Il semble y avoir au moins un (non résolu?) issue avec require dans certains cas.

+0

Dupliquer: http://stackoverflow.com/questions/129226/what-are-the-current-state-of-affairs-on-threading-concurrency-and-forked-proces/129331#129331 –

Répondre

5

La solution normale pour l'IRM est d'exécuter plusieurs instances Rails, chacune traitant les demandes indépendamment. Puisque l'IRM n'est pas multithread de toute façon, vous ne pouvez pas exécuter plusieurs instances de Rails au-dessus. Cela signifie que vous prenez un souvenir car Rails est chargé une fois par processus Ruby.

Étant donné que JRuby prend en charge les threads natifs, vous pouvez toujours exécuter plusieurs instances Rails dans une même JVM. Mais avec Rails étant thread-safe, vous pouvez le réduire à un, ce qui signifie moins d'utilisation de la mémoire et moins de compilation JIT.

Charles Nutter (JRuby) a un nice summary.

+0

Merci, Charles Le résumé de Nutter est génial. – auramo

1

Je pense que les affiches précédentes ont assez bien couvert les cas de Rails, donc je ne vais pas prendre la peine d'aller dans ce genre de choses.

Il est certainement possible d'écrire des applications Ruby filetées. Certains des problèmes qui existent avec les threads ruby ​​sont qu'ils sont "verts" car ils sont gérés par la machine virtuelle. Actuellement, l'interpréteur par défaut (MRI) a seulement un vrai thread système qui doit être partagé par tous les threads sur lesquels l'interpréteur a le contrôle. L'inconvénient de ceci est que si vous avez un ordinateur avec plusieurs processeurs ou cœurs, vous ne pouvez pas avoir un thread dans votre application fonctionnant sur un autre noyau. C'est un gros problème pour les utilisateurs de serveurs et d'applications hautes performances.En ce qui concerne votre question de code spécifique à un interprète: Je ne pense pas. AFAIK vous n'avez rien à faire de spécial pour prendre soin des threads JRuby/JVM.

Egalement: This article sur Igvita qui examine bien l'état de la simultanéité dans Ruby. Tout d'abord, Ruby 1.9 (la plus récente version officielle) now uses native (kernel) threads

14

Les versions précédentes de Ruby utilisaient des fils verts. Pour répondre à votre question succinctement, avant 1.9, les threads ne sont généralement pas utilisés dans les applications Ruby grandes ou petites précisément parce qu'ils ne sont pas particulièrement sûrs ou fiables. Ceci n'est pas particulièrement alarmant car, avant la version 2.2, Rails n'essayait pas d'assurer la sécurité des threads. Nous traitons donc généralement les processus asynchrones en utilisant plusieurs processus, le verrouillage des enregistrements de base de données et les files d'attente de messages comme Starling. Il s'agit généralement d'un moyen assez fiable pour mettre à l'échelle une application Web - au moins aussi fiable que des applications Java multithread incorrectes - et présente l'avantage supplémentaire de faciliter l'évolutivité de votre application vers plusieurs processeurs et serveurs. Je n'ai aucune idée si le problème 'require' que vous avez mentionné a été résolu à partir de 1.9, mais je me permets humblement que si vous avez besoin de bibliothèques dynamiquement dans de nouveaux threads alors vous avez plus d'un problème de maintenabilité. Si vous souhaitez éviter les threads entièrement, Ruby 1.9 also supports fibers, qui utilisent une approche de type «shared-nothing» pour la concurrence et qui, d'après ce que je comprends, sont généralement plus faciles à écrire et à gérer que les threads. Performance numbers here.

+0

Pourquoi est-il utile de comparer * n'importe quoi * aux "applications Java * incorrectement * multithread"? –

+0

@KirkWoll Ma lecture était que le répondeur impliquait que "lorsque le filetage est dangereux dans une langue, il peut ne pas en valoir la peine dans cette langue." – Jackson

Questions connexes