18

Di tanto in tanto ho hackerato con Ruby, ma non ho fatto nulla di grosso o di multithreading con esso. Ho sentito che la risonanza magnetica supporta solo i thread verdi e JRuby supporta i thread nativi tramite JVM. Tuttavia, mi imbatto in commenti su blog e gruppi di discussione che dicono che "Rails non è thread-safe" o che Ruby non è thread-safe. Ad esempio, qualcuno ha commentato che c'è un problema con la dichiarazione require. Sembra un po 'fondamentale.Sicurezza thread di ruby ​​/ rails

ho visto un sacco di applicazioni Java che non gestiscono correttamente concorrenza e non ho incubi su di loro di volta in volta :-) Ma almeno si può applicazioni thread-safe scrittura in Java se davvero sai cosa stai facendo (non è semplice).

Questo suona abbastanza allarmante, qualcuno può elaborare di più - qual è esattamente il problema e come Rails riesce a funzionare affatto se questo è il caso? Posso scrivere il codice Ruby multithread che funzioni correttamente senza condizioni di gara e deadlock? È trasportabile tra JRuby e MRI o devo eseguire il login in codice JVM specifico per sfruttare correttamente i thread nativi JVM?

EDIT:

avrei dovuto chiedere due domande, perché la gente sembra solo per rispondere alle rotaie filettatura roba (che è bello in sé) e la filettatura verde contro filettatura nativo. Le mie preoccupazioni sui problemi fondamentali di Ruby relativi alla sicurezza del thread non sono state effettivamente risolte con il. Sembra esserci almeno un (irrisolto?) issue con richiesta in alcuni casi.

+0

Duplicato: http://stackoverflow.com/questions/129226/questo-sono-il-attuale-statuto-della-affare-con-corrente-concorrente-e-fappunto-prodotto/129331#129331 –

risposta

5

La soluzione normale per la risonanza magnetica consiste nell'eseguire più istanze di Rails, ognuna delle quali gestisce le richieste in modo indipendente. Poiché la risonanza magnetica non è comunque multithread, non è possibile eseguire più istanze di Rails su di essa. Ciò significa che si verifica un errore di memoria poiché Rails viene caricato una volta per processo Ruby.

Poiché JRuby supporta i thread nativi, è sempre possibile eseguire diverse istanze di Rails in una singola JVM. Ma con Rails che è thread-safe, puoi ridurlo a uno, il che significa un minore utilizzo della memoria e meno compilazioni JIT.

Charles Nutter (JRuby) ha uno nice summary.

+0

Grazie, Charles Il riassunto di Nutter è fantastico. – auramo

1

Penso che i poster precedenti riguardassero abbastanza bene i casi di Rails, quindi non mi preoccuperei di entrare in quel genere di cose.

È certamente possibile scrivere applicazioni Ruby con thread. Alcuni dei problemi che esistono con i thread in ruby ​​è che sono "verdi" in quanto sono gestiti dalla macchina virtuale. Attualmente, l'interprete predefinito (MRI) ha solo un thread di sistema vero che deve essere condiviso da tutti i thread su cui l'interprete ha il controllo.

Lo svantaggio di questo è che se si dispone di un computer con più processori o core non è possibile avere un thread nell'applicazione in esecuzione su un altro core. Questo è un grosso problema per le persone che gestiscono server e app ad alte prestazioni.

Come per la domanda relativa al codice specifico dell'interprete: non la penso così. AFAIK non devi fare nulla di speciale per occuparti dei thread JRuby/JVM.

Inoltre: This article su Igvita che dà una buona occhiata allo stato di concorrenza in Ruby.

14

Prima di tutto, Ruby 1.9 (la versione ufficiale più recente) now uses native (kernel) threads. Le versioni precedenti di Ruby utilizzavano fili verdi. Per rispondere alla tua domanda in modo succinto, prima di 1.9, i thread non sono stati comunemente usati nelle applicazioni Ruby grandi o piccoli proprio perché non sono particolarmente sicuri o affidabili.

Questo non è particolarmente allarmante perché prima versione 2.2 rotaie fatto alcun tentativo di essere threadsafe, e così tipicamente gestire l'elaborazione asincrona attraverso l'uso di più processi, il blocco record del database e code di messaggi come Starling. Questo è generalmente un modo abbastanza affidabile per scalare un'applicazione Web, almeno altrettanto affidabile di applicazioni Java con multithreading errato, e ha il vantaggio aggiunto che è più semplice scalare l'applicazione lateralmente su più processori e server.

Non ho idea se il problema "richiedi" che hai menzionato sia stato risolto a partire dal 1.9, ma mi compiaccio umilmente che se stai richiedendo le librerie dinamicamente in nuovi thread, allora hai più di un problema di manutenibilità.

Se si desidera evitare completamente thread, Ruby 1.9 also supports fibers, che impiegano un approccio condiviso-niente alla concorrenza e, da quello che ho raccolto, in genere è più facile da scrivere e gestire rispetto ai thread. Performance numbers here.

+0

Perché è utile confrontare * qualsiasi * con "* erroneamente * applicazioni Java multithread"? –

+0

@KirkWoll La mia lettura era che il rispondente stava insinuando che "quando il threading è pericoloso in una lingua, potrebbe non valerne la pena in quella lingua". – Jackson