понедельник, 25 июля 2011 г.

Многопоточность GTK и lightweight потоки в Haskell. Ошибка новичка

Сегодня впервые попробовал Gtk2Hs. Пробовал его в купе с Gazpacho, о котором писал ранее. Интуитивно-понятная архитектура GTK в купе с подробнейшей документацией в Haddock сделали мне приятный вечер.

Для закрепления успеха я решил написать простенькую утилиту. Быстренько накидав формочки и вдумчиво, но так же быстро написав код, я принялся за тестирование.

Не дав даже оглядеться, меня ловко спустили с небес.
Получив такую ошибку я даже и не знал о чем думать:
Gtk:ERROR:gtktextview.c:3571:gtk_text_view_validate_onscreen: assertion failed: (text_view->onscreen_validated)

Функции работающие с GtkTextView были использованы верно. 

Во время чтения различных туториалов, глаза натыкались на отрывки со словами "gtk" и "multithreading". 
В коде я имел функцию, которая вызывается с помощью forkIO и внутри использует threadDelay.

Оказалось, что запуск mainGUI  включает в работу треды GTK, которые отвечают за event'ы и все, что касается GUI. И во время работы главного цикла (main loop, если удобнее) GTK - все  легковесные процессы вовсе не должны запускаться.

Но функция, запускаемая через forkIO работала с правильной периодичностью и выполняла свою работу. Раза два, до падения. :)

Поэтому простенький forkIO мы должны заменить на timeoutAddFull.
Цитирую Real World Haskell:
Вызов timeoutAddFull нужен лишь для многопоточных GTK+ программ. Данная функция "просит" главный цикл (main loop) сделать паузу, дабы дать шанс другим потокам запуститься.

Первым аргументом функция timeoutAddFull получает другую функцию, которая должна возвращать IO Bool. Эта другая функция будет промежуточно запускаться до тех пор, пока не вернет False.

На самом деле это прописные истины и мне очень жаль, что я так мало работал с программированием GUI.

Комментариев нет:

Отправить комментарий