Название: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 15, 2009, 13:24 Задача.
1) Имеем объект некоторого класса, имеем метод который может быть вызван в любом потоке(в зависимости от ситуации), как в главном, так и в вспомогательном. 2) Выполнение данного метода может быть очень длительным и как правило для его выполненния создается вспомогательный поток 3) В данном методе есть вызов другого метода в котором происходит создание некоторого QWidget 4) Проблема в том что QWidget могут создаваться только в главном потоке. Как сделать внутри второстепенного потока вызов метода в контексте главного потока? В билдере у класса TThread для этих целей был "syncronize(method)", есть ли что-либо подобное в QT, а если нет, то как решить проблему? Название: Re: QThread - синхронизация с главным потоком. Отправлено: ритт от Июль 15, 2009, 17:15 в контексте QApplication или TL Widget приписать слот, создающий необходимый виджет. из п.3 асинхронно вызывать данный слот.
насколько я помню, багландовский syncronize замораживает задействованные потоки... Название: Re: QThread - синхронизация с главным потоком. Отправлено: alexman от Июль 15, 2009, 22:13 Например, можно послать сигнал из вспомогательного потока главному на создание QWidget и уснуть на QWaitCondition (метод bool wait ( QMutex * mutex, unsigned long time = ULONG_MAX )). Далее в главном окне что-то делаем с QWidget, а по завершению вызываем метод второстепенного потока из главного, в котором делаем wakeOne.
Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 16, 2009, 11:48 Спасибо Константин и alexman.
Вроде работает. Если есть желание, посмотрите что получилось, может что еще поскажете или найдете ошибки. синхронизация делается через наследника SbThreadSync, вызовом статического метода SbThread::synchronize(SbThreadSync* s); Еще сделан #define sb_synchronize_method. Можно делать синхронизацию так: Код
Далее исходники sbw_kernel.h Код
sbw_kernel.cpp Код
Название: Re: QThread - синхронизация с главным потоком. Отправлено: Winstrol от Июль 16, 2009, 16:35
Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 16, 2009, 19:07 Во-первых, help по Qt::ConnectionType. Ну и что? Что плохого в том что я явно указал Qt::QueuedConnectionВо-вторых, низкоуровневые примитивы вроде QMutex,QAtomicInt и.т.п. в прикладном коде следует всячески избегать, т.к. при наличии QtConcurrent они тупо практически никогда не нужны, а если и нужны, то часто есть более лучшие решения без них. Покажи решение лучше!В-третьих, что будет проснется A! Поток A шлет сигнал главному потоку сигнал на создание QWidget и засыпает. Поток B шлет сигнал главному потоку сигнал на создание QWidget и засыпает. Главный поток создает QWidget по запросу потока А и делает wakeOne. Вопрос? Какой поток проснется A или B. У них разные QWaitCondition, смотри код. Название: Re: QThread - синхронизация с главным потоком. Отправлено: Winstrol от Июль 16, 2009, 21:10 Ну и что? Что плохого в том что я явно указал Qt::QueuedConnection help по Qt::ConnectionTypeЦитировать Покажи решение лучше! help по Qt::ConnectionTypeЦитировать У них разные QWaitCondition, смотри код. Извиняюсь, не посмотрел. Жесть! Чистая и незамутненная.Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 16, 2009, 21:49 Ну и что? Что плохого в том что я явно указал Qt::QueuedConnection help по Qt::ConnectionTypeЦитировать Покажи решение лучше! help по Qt::ConnectionTypeЦитировать У них разные QWaitCondition, смотри код. Извиняюсь, не посмотрел. Жесть! Чистая и незамутненная.??? Название: Re: QThread - синхронизация с главным потоком. Отправлено: Winstrol от Июль 16, 2009, 22:15 Для тех, у кого устаревший хелп, правильный ответ:
QMetaObject::invokeMethod(&...,"addWidget",Qt::BlockingQueuedConnection); или emit addWidget(); Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 16, 2009, 23:22 Для тех, у кого устаревший хелп, правильный ответ: Qt::BlockingQueuedConnection - возможно, только не совсем понятно что значит:QMetaObject::invokeMethod(&...,"addWidget",Qt::BlockingQueuedConnection); или emit addWidget(); Цитировать Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. delivered - "доставлен" или "освобожден" - совершенно разный смысл, и понимай как хочешь! Если именно освобожден, то можно обойтись и без QMutex и QWaitCondition.А QMetaObject::invokeMethod - не интересно, покольку задача выполнить любой метод/методы (любого объекта или обычный метод) из дочернего потока в контексте главного. Название: Re: QThread - синхронизация с главным потоком. Отправлено: ритт от Июль 16, 2009, 23:31 Для тех, у кого устаревший хелп, правильный ответ: Qt::BlockingQueuedConnection - возможно, только не совсем понятно что значит:QMetaObject::invokeMethod(&...,"addWidget",Qt::BlockingQueuedConnection); или emit addWidget(); Цитировать Same as QueuedConnection, except that the current thread blocks until the slot has been delivered. delivered - "доставлен" или "освобожден" - совершенно разный смысл, и понимай как хочешь! Если именно освобожден, то можно обойтись и без QMutex и QWaitCondition.А QMetaObject::invokeMethod - не интересно, покольку задача выполнить любой метод/методы (любого объекта или обычный метод) из дочернего потока в контексте главного. А QMetaObject::invokeMethod именно это и делает.Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 17, 2009, 09:36 доставлен. для блокировки потока используется мутекс (если правильно помню). пока ивент не будет доставлен, мутекс не разблокируется. Я правильно тебя понял, "доставлен" - момент непосредственно перед вызовом слота.А QMetaObject::invokeMethod именно это и делает. Согласен, но в данном случае, что через сигнал, что через него - особой разницы нет.Название: Re: QThread - синхронизация с главным потоком. Отправлено: ритт от Июль 17, 2009, 10:11 сигнализируя, ты не можешь ожидать момент доставки - поведение зависит целиком от connect
в случае же с invokeMethod ты сам можешь определять как будет вести себя конкретный клочок кода - в одном месте можно дожидаться доставки, в другом - нет...вдобавок для использования не требуется макрос Q_OBJECT и для ряда случаев сигналы вообще. Название: Re: QThread - синхронизация с главным потоком. Отправлено: Winstrol от Июль 17, 2009, 10:40 доставлен. для блокировки потока используется мутекс (если правильно помню). пока ивент не будет доставлен, мутекс не разблокируется. Я правильно тебя понял, "доставлен" - момент непосредственно перед вызовом слота.Цитировать void SbThread::wake (void) { Может получить управление до waitWait.wakeOne(); } Название: Re: QThread - синхронизация с главным потоком. Отправлено: spectre71 от Июль 17, 2009, 17:17 Может получить управление до wait Если я привильно понял(QWaitCondition::wait) Цитировать This function is provided to allow the atomic transition from the locked state to the wait state. Тогда так Код
|