Si suppone che Ruby 1.9 disponga di thread nativi e GIL dovrebbe sollevare se alcuni thread immettono codice nativo (come il loop principale del toolkit GUI o implementazione di C di una lib di Ruby).Perché la GUI di Ruby 1.9 si blocca se eseguo calcoli intensivi in thread Ruby separati?
Ma se inizio a seguire un semplice esempio di codice che mostra la GUI nel thread principale e faccio alcuni calcoli matematici di base in thread separati - la GUI si bloccherà, provate a ridimensionare la finestra per vederla da soli. Ho controllato con diversi GUI toolkit, Qt (qtbindings gem) - si comporta esattamente allo stesso modo. Testato con Ruby 1.9.3-p0 su Windows 7 e OSX 10,7
require 'tk'
require 'thread'
Thread.new { loop { a = 1 } }
TkRoot.new.mainloop()
stesso codice in Python funziona bene senza alcuna interfaccia grafica si blocca:
from Tkinter import *
from threading import *
class WorkThread(Thread) :
def run(self) :
while True :
a = 1
WorkThread().start()
Tk().mainloop()
quello che sto facendo di sbagliato?
UPDATE
Sembra dove è nessun problema su Ubuntu Linux, quindi la mia domanda è principalmente su Windows e OSX.
UPDATE
Alcune persone osserva che, mentre non è un problema del genere su OSX. Così ho preparato una guida passo-passo per isolare e riprodurre un problema:
- Installare OSX 10.7 Lion tramite la funzione "Ripristino". Ho usato il nostro reparto test MB139RS/A mac mini per il test.
- Installa tutti gli aggiornamenti. Il sistema sarà simile a questa:
- installare l'ultima ActiveTcl da activestate.com, nel mio caso è ActiveTcl 8.5.11 per OSX.
- Scaricare e decomprimere l'ultimo codice sorgente di Ruby. Nel mio caso è Ruby 1.9.3-p125. Compilalo e installa il sistema di sostituzione Ruby (comandi di seguito). Si finirà con l'ultimo rubino con supporto Tk integrato:
- Creare un file
test.rb
con codice dal mio esempio ed eseguirlo. Prova a ridimensionare una finestra: vedrai terribili ritardi. Rimuovi il thread dal codice, avvia e prova a ridimensionare una finestra: i ritardi sono spariti. Ho registrato un video of this test.
Rubino compilazione:
./configure --with-arch=x86_64,i386 --enable-pthread --enable-shared --with-gcc=clang --prefix=/usr
make
sudo make install
Non sicuro, ma Ruby 1.9 ha ancora un GIL (Global Interpreter Lock)? Questo spiegherebbe completamente il tuo problema ... – Romain
@Romain In che modo GIL spiega il mio problema? Python ha lo stesso GIL e nessun problema. – grigoryvp
GIL significa che solo un singolo thread può eseguire il codice ruby in una volta, quindi se il calcolo in background può utilizzarlo, il tuo codice UI non può. – Romain