Название: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 22:27 В основном потоке уйти в ожидание, пока два параллельных потока не выдадут свои сигналы. Оба, то есть, надо получить оба сигнала, и только после этого продолжить выполнение. Хотел было сделать так:
основной поток: Код: QMutex m( QMutex::Recursive ); соответственно в слотах для сигналов от потоков 1 и 2, в обоих: Код: w.wakeOne(); но облом, в мануале написано, что w.wait() освободит кумутекс, если он рекурсивный - проверил, действительно, wait проскакивает вот пока что-то не могу придумать изящное решение на ночь глядя, оно наверняка очень простое, может кто подскажет? хотелось бы, чтобы без перезапуска ожидания в ловушках сигналов, так я без подсказки могу сделать Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 22:43 QSemaphore?
Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 22:51 ну и как его в главном потоке приложения использовать? задерживать два других потока мне не нужно - они присылают сигналы, когда им надо, через QueuedConnection, и как-то сами крутятся
то есть, в классе, который в главном потоке должен их подождать, есть два слота приемников этих сигналов как тут QSemaphore прикрутить? кто и как делает wait()? особенно, с учетом, что это все находится хоть и в главном потоке, но не в основном приложении - это в плагине Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 22:54 Про семафор это скорее были мысли в слух...
"wait" делает он сам при попытке захватить ресурс сверх лимита. Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:00 Цитировать Про семафор это скорее были мысли в слух... аааа... Цитировать wait делает он сам при попытке захватить ресурс сверх лимита. это я понимаю, поэтому с семафорами тоже ерунда получается - он не может остановиться до тех пор, пока ДВА ресурса не освободятся, он побежит дальше, как только освободится один Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:09 Основной поток:
Код
Изначально numThread = 2, каждый поток при завершении должен сделать декремент под защитой мутекса m, ну и wakeOne. Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:19 Основной поток: Код
Изначально numThread = 2, каждый поток при завершении должен сделать декремент под защитой мутекса m, ну и wakeOne. надо разобраться... Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:22 Так тут никакая остановка главного потока не подойдет, т.к. нужно постоянно крутить очередь событий для обработки сигналов. ::)
Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:24 QWaitCondition на очередь событий не влияет
Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:25 Влияет, wait поток останавливает! Иначе в нем смысла не было бы. :)
Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:35 он останавливает только главный поток, но не обработку событий, иначе у меня не работали бы "двунаправленные сокет-слоты", то есть, "сигналы с возвратом значения", вот такие:
Код: void class::sender( int somevalue ) Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:40 а зачем там QMutexLocker ? какой в нем тут смысл?
Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:44 wait таймеры не использует.
А зачем ты у wait таймаут используешь? А если его убрать? Ну и твой кусок кода ничего не показывает, ни очередь событий, ни "сигналы с возвратом значений". Главное! wait останавливает поток, наглухо. Останавливается все, включая очередь сообщений. Это то, для чего он предназначен. ;) Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:45 а зачем там QMutexLocker ? какой в нем тут смысл? Безопасно залочить мьютекс.Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 25, 2011, 23:47 я строку добавил, которая показывает, зачем таймаут - если другой объект не отозвался, то считается, что результат 0.0
но ведь у меня это все работает через соединения QueuedConnection, и что еще смешнее - другой объект, который сигнал принимает, тоже в главном потоке находится Цитировать твой кусок кода ничего не показывает, ни очередь событий, ни "сигналы с возвратом значений" так показывает? Код: Объект1::<сигнал>send(somevalue) --> Объект2::<слот>recevie(somevalue)...чего-то сделал...Объект2::<сигнал>sendresult(returnedvalue) --> Объект1::<слот>receiver(returnedvalue) оба объекта в главном потоке, все работает на ура, несмотря на wait() если соединения нет (второй объект в другом плагине, а он может быть не загружен), то через 1 секунду получаю 0.0, если соединение есть, то ответ от второго объекта а думаю, wait где-то внутри упирается в qnoop(), который в основном цикле ожидания используется Цитировать Безопасно залочить мьютекс. а какая может быть опасность? Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:51 Вставь вот такую строку в разные места и посмотри в каких потоках точно работает код. Что то мне подсказывает, что ты будешь удивлен результатом. ;)
Код
Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 25, 2011, 23:53 а какая может быть опасность? Код
Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 26, 2011, 00:05 Вставь вот такую строку в разные места и посмотри в каких потоках точно работает код. Что то мне подсказывает, что ты будешь удивлен результатом. ;) а, не... вспомнил... это используется действительно, только с объектом, работающим в другом потоке уже час ночи, спать пора... Цитировать Мутекс m останется залоченным. С QMutexLocker такое не возможно. ну в моем случае такого не будет Название: Re: Надо дождаться двух сигналов Отправлено: Igors от Август 26, 2011, 10:16 Ну просто "дождаться" нет проблем
Код Но это остановит нитку полностью, ничего принять она не сможет пока ее с семафора не снимут др. нитки. Поэтому выглядит так что ничего останавливать/синхронизировать не надо. Крутится себе нитка в eventLoop - ну и пусть. Когда оба нужных сигнала приняты (напр прjверить по if) - начинается какое-то действие Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 26, 2011, 12:08 Цитировать это остановит нитку полностью, ничего принять она не сможет пока ее с семафора не снимут др. нитки. не, это ерунда Цитировать выглядит так что ничего останавливать/синхронизировать не надо. мало ли что как со стороны выглядит... два независимых плагина, работающих в отдельных потоках, проводят инициализацию и сообщают об этом сигналами, основной поток не может продолжать работу дальше, пока они этого не сделают BRE в конце предыдущей страницы предложил решение, похожее на то, что надо, только там счетчик при приеме сигналов надо не мутексом m защищать, а еще одним мутексом, m занят ожидателем w пока руки не дошли реализовать, другое дело подвернулось, но идея правильная Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 26, 2011, 12:11 только там счетчик при приеме сигналов надо не мутексом m защищать, а еще одним мутексом, m занят ожидателем w Разберись как работают условные переменные. :)m ничем не занят. wait разлочит этот мьютекс при остановке и залочит его заново при просыпании. Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 26, 2011, 12:27 Цитировать wait разлочит этот мьютекс при остановке и залочит его заново при просыпании где об этом написано? Название: Re: Надо дождаться двух сигналов Отправлено: Igors от Август 26, 2011, 12:36 два независимых плагина, работающих в отдельных потоках, проводят инициализацию и сообщают об этом сигналами, основной поток не может продолжать работу дальше, пока они этого не сделают Ну значит главная нитка должна принять эти сигналы и блокировать ее нельзя. А "остановить работу" можно напр такКод
Название: Re: Надо дождаться двух сигналов Отправлено: BRE от Август 26, 2011, 12:58 где об этом написано? Поищи в нете описание работы pthread_cond_wait.Добавил: ну и в документации на QWaitCondition::wait все подробно расписано. Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 26, 2011, 12:58 Цитировать while (true) { if (plugin1Ready && plugin2Ready) break; QThread::yieldCirrentThread(); QApplication::processEvents(); } а вот это уже ерунда - загрузка процессора на 60%, плюс невозможность обработать ситуацию, когда один плагин не загружен, в варианте BRE такая обработка делается просто добавлением таймаута в wait( &m, 3000 ) - через 3 секунды, если плагины не проинициализировались (выясняется проверкой на то, что numThread по прежнему равен 2), катим дальше, выдаем сообщение об ошибке плагина, и нормально завершаемся Название: Re: Надо дождаться двух сигналов Отправлено: Igors от Август 26, 2011, 14:42 в варианте BRE такая обработка делается просто добавлением таймаута в wait( &m, 3000 ) - через 3 секунды, если плагины не проинициализировались (выясняется проверкой на то, что numThread по прежнему равен 2), катим дальше, выдаем сообщение об ошибке плагина, и нормально завершаемся Можно и так, но тогда без сигналов, и на 3 сек UI заморожена вот это уже ерунда - загрузка процессора на 60%, плюс невозможность обработать ситуацию, когда один плагин не загружен, Про флажки для processEvents почитайте - чтоб не загружать процессор. И вообще - лучше сначала разобраться а потом резво кричать "ерунда-ерунда" :)Умолкаю.. Название: Re: Надо дождаться двух сигналов Отправлено: Гурман от Август 26, 2011, 14:46 Цитировать тогда без сигналов с сигналами, они из других потоков приходят, и нормально отрабатывают Название: Re: Надо дождаться двух сигналов Отправлено: SASA от Август 26, 2011, 15:36 Цитата: Гурман link=topic=19234.msg129815#msg129815 ну в моем случае такого не будет [/quote Чтоб не думать о случаях, лучше всегда пользоваться QMutexLocker. По теме. А не проще завести флаг типа intitOk. (код из головы) Код: enum intit |