Многопоточность в wxWidgets (Как лучше реализовать?)

Модератор: Модераторы разделов

Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Многопоточность в wxWidgets

Сообщение KonishchevDmitry »

Господа.. :rolleyes:
Начал знакомиться с wxWidgets. Возник такой вопрос:
Допустим я пишу приложение, в котором у меня работает несколько потоков, и при этом каждый из них время от времени делает что-то с GUI. В принципе, можно каждое обращение потока к GUI окружать вызовами wxMutexGuiEnter() и wxMutexGuiLeave(), но в документации к wxWidgets в секции Multithreading overview написано следующее:
If you do decide to use threads in your application, it is strongly recommended that no more than one thread calls GUI functions. The thread sample shows that it is possible for many different threads to call GUI functions at once (all the threads created in the sample access GUI), but it is a very poor design choice for anything except an example. The design which uses one GUI thread and several worker threads which communicate with the main one using events is much more robust and will undoubtedly save you countless problems (example: under Win32 a thread can only access GDI objects such as pens, brushes, &c created by itself and not by the other threads).
Т. е., если вкратце, то: "Лучше так не делайте. Спроектируйте приложение так, чтобы весь интерфейс изменял только один (main) поток, а остальные только взаимодействовали бы с ним через систему событий."
Так вот что они имеют в виду под взаимодействием через события? Ткните ссылкой, пожалуйста.
Спасибо сказали:
Аватара пользователя
halturin
Сообщения: 167
ОС: Linux

Re: Многопоточность в wxWidgets

Сообщение halturin »

KonishchevDmitry писал(а):
04.01.2008 23:06
Господа.. :rolleyes:
Начал знакомиться с wxWidgets. Возник такой вопрос:
Допустим я пишу приложение, в котором у меня работает несколько потоков, и при этом каждый из них время от времени делает что-то с GUI. В принципе, можно каждое обращение потока к GUI окружать вызовами wxMutexGuiEnter() и wxMutexGuiLeave(), но в документации к wxWidgets в секции Multithreading overview написано следующее:
If you do decide to use threads in your application, it is strongly recommended that no more than one thread calls GUI functions. The thread sample shows that it is possible for many different threads to call GUI functions at once (all the threads created in the sample access GUI), but it is a very poor design choice for anything except an example. The design which uses one GUI thread and several worker threads which communicate with the main one using events is much more robust and will undoubtedly save you countless problems (example: under Win32 a thread can only access GDI objects such as pens, brushes, &c created by itself and not by the other threads).
Т. е., если вкратце, то: "Лучше так не делайте. Спроектируйте приложение так, чтобы весь интерфейс изменял только один (main) поток, а остальные только взаимодействовали бы с ним через систему событий."
Так вот что они имеют в виду под взаимодействием через события? Ткните ссылкой, пожалуйста.


wx-виджеты - это графические элементы на базе GTK/GDK, так что нужно смотреть туда на предмет работы в многопоточном режиме, вот тебе ключевые слова:

g_thread_init
gdk_threads_init
gdk_threads_enter
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Многопоточность в wxWidgets

Сообщение KonishchevDmitry »

halturin писал(а):
05.01.2008 10:36
wx-виджеты - это графические элементы на базе GTK/GDK, так что нужно смотреть туда на предмет работы в многопоточном режиме, вот тебе ключевые слова:

g_thread_init
gdk_threads_init
gdk_threads_enter
Не согласен с вами. :) wxWidgets - это библиотека, которая использует другие графические библиотеки в зависимости от платформы: на Linux это чаще всего GTK, в Mac - Carbon API, в Windows - windows'овские нативные виджеты (или как они там называются - GDI и пр.). Поэтому искать следует именно внутри wxWidgets, а не в отдельной библиотеке (GTK). К тому же приведенные вами функции - это как раз аналог wxMutexGuiEnter() и wxMutexGuiLeave() в wxWidgets, применения которых я как раз и хочу избежать.

P.S.: Кстати, даже если бы я захотел использовать g_thread_init, gdk_threads_init и gdk_threads_enter под wxWidgets, то я бы никак не смог бы это сделать, т. к. g_thread_init нужно вызывать в основном потоке перед вызовом gtk_init, а при программировании в wxWidgets у вас в вашей программе даже нет явно присутствующей функции main(). Ее заменяет макрос IMPLEMENT_APP(), который в зависимости от платформы генерирует свой main().
Спасибо сказали:
andy128k
Сообщения: 28
ОС: GNU/Linux

Re: Многопоточность в wxWidgets

Сообщение andy128k »

KonishchevDmitry писал(а):
04.01.2008 23:06
Так вот что они имеют в виду под взаимодействием через события? Ткните ссылкой, пожалуйста.

Потоки не должны напрямую взаимодействовать с GUI, а должны генерировать события.
Вот. нагуглил. http://www.wxwidgets.org/manuals/2.8/wx_wx...xthreadoverview http://www.wxwidgets.org/manuals/2.8/wx_ev...andlingoverview
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Многопоточность в wxWidgets

Сообщение KonishchevDmitry »

andy128k писал(а):
05.01.2008 11:26
Потоки не должны напрямую взаимодействовать с GUI, а должны генерировать события.
Вот. нагуглил. http://www.wxwidgets.org/manuals/2.8/wx_wx...xthreadoverview http://www.wxwidgets.org/manuals/2.8/wx_ev...andlingoverview
Да, но в примерах, которые описываются в http://www.wxwidgets.org/manuals/2.8/wx_ev...andlingoverview собственное событие вызывается из основного потока, и ничего не говорится о том, нужно ли выполнять какие-то блокировки при вызове GetEventHandler()->ProcessEvent(event) из других потоков. Ведь это скорее всего необходимо.
Спасибо сказали:
andy128k
Сообщения: 28
ОС: GNU/Linux

Re: Многопоточность в wxWidgets

Сообщение andy128k »

KonishchevDmitry писал(а):
05.01.2008 12:07
Да, но в примерах, которые описываются в http://www.wxwidgets.org/manuals/2.8/wx_ev...andlingoverview собственное событие вызывается из основного потока, и ничего не говорится о том, нужно ли выполнять какие-то блокировки при вызове GetEventHandler()->ProcessEvent(event) из других потоков. Ведь это скорее всего необходимо.

А здесь http://www.wxwidgets.org/manuals/2.8/wx_wx...xthreadoverview указано
For communication between secondary threads and the main thread, you may use wxEvtHandler::AddPendingEvent or its short version wxPostEvent. These functions have a thread-safe implementation so that they can be used as they are for sending events from one thread to another.

:)
Спасибо сказали:
Аватара пользователя
KonishchevDmitry
Сообщения: 92
ОС: Ubuntu

Re: Многопоточность в wxWidgets

Сообщение KonishchevDmitry »

andy128k, да, похоже, мои глаза начинают меня подводить. :) Почему-то совсем не обратил внимания на этот абзац. Спасибо большое, буду пробовать.
Спасибо сказали: