Предполагается, что Ruby 1.9 имеет собственные потоки, и GIL должен поднять, если некоторые потоки входят в собственный код (например, основной цикл инструментария GUI или реализация C некоторой библиотеки Ruby lib).
Но если я начну следовать простейшему образцу кода, который отображает графический интерфейс в основном потоке и выполняет некоторую базовую математику в отдельном потоке - GUI будет плохо болтаться, попробуйте изменить размер окна, чтобы увидеть его самостоятельно. Я проверил с помощью другого инструментария GUI, Qt (qtbindings gem) - он ведет себя точно так же. Протестировано с Ruby 1.9.3-p0 в Windows 7 и OSX 10.7
require 'tk'
require 'thread'
Thread.new { loop { a = 1 } }
TkRoot.new.mainloop()
Тот же код в Python отлично работает без зависания GUI:
from Tkinter import *
from threading import *
class WorkThread( Thread ) :
def run( self ) :
while True :
a = 1
WorkThread().start()
Tk().mainloop()
Что я делаю неправильно?
UPDATE
Кажется, где нет такой проблемы в Linux Ubuntu, поэтому мой вопрос в основном касается Windows и OSX.
UPDATE
Некоторые люди отмечают, что в OSX нет такой проблемы. Поэтому я собрал пошаговое руководство, чтобы изолировать и воспроизвести проблему:
- Установите OSX 10.7 Lion через функцию "Восстановление". Я использовал наш тестовый отдел MB139RS/Mac mac для тестирования.
- Установить все обновления. Система будет выглядеть так:
- Установите последний ActiveTcl с сайта activestate.com, в моем случае это ActiveTcl 8.5.11 для OSX.
- Загрузите и распакуйте последний исходный код Ruby. В моем случае это Ruby 1.9.3-p125. Скомпилируйте его и установите заменяющую систему Ruby (команды ниже). В итоге вы получите новейший рубин со встроенной поддержкой Tk:
- Создайте файл
test.rb
с кодом из моего примера и запустите его. Попробуйте изменить размер окна - вы увидите ужасные запаздывания. Удалите нить из кода, запустите и попробуйте изменить размер окна - отставания ушли. Я записал видео этого теста.
Команды компиляции Ruby:
./configure --with-arch=x86_64,i386 --enable-pthread --enable-shared --with-gcc=clang --prefix=/usr
make
sudo make install