Russian Qt Forum
Ноябрь 22, 2024, 23:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Надо дождаться двух сигналов  (Прочитано 10774 раз)
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« : Август 25, 2011, 22:27 »

В основном потоке уйти в ожидание, пока два параллельных потока не выдадут свои сигналы. Оба, то есть, надо получить оба сигнала, и только после этого продолжить выполнение. Хотел было сделать так:

основной поток:

Код:
    QMutex m( QMutex::Recursive );
    m.lock();
    m.lock();
    QWaitCondition w;
    w.wait( &m );

соответственно в слотах для сигналов от потоков 1 и 2, в обоих:

Код:
    w.wakeOne();

но облом, в мануале написано, что w.wait() освободит кумутекс, если он рекурсивный - проверил, действительно, wait проскакивает

вот пока что-то не могу придумать изящное решение на ночь глядя, оно наверняка очень простое, может кто подскажет? хотелось бы, чтобы без перезапуска ожидания в ловушках сигналов, так я без подсказки могу сделать
Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #1 : Август 25, 2011, 22:43 »

QSemaphore?
« Последнее редактирование: Август 25, 2011, 22:51 от BRE » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #2 : Август 25, 2011, 22:51 »

ну и как его в главном потоке приложения использовать? задерживать два других потока мне не нужно - они присылают сигналы, когда им надо, через QueuedConnection, и как-то сами крутятся

то есть, в классе, который в главном потоке должен их подождать, есть два слота приемников этих сигналов

как тут QSemaphore прикрутить? кто и как делает wait()? особенно, с учетом, что это все находится хоть и в главном потоке, но не в основном приложении - это в плагине
« Последнее редактирование: Август 25, 2011, 22:54 от Гурман » Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #3 : Август 25, 2011, 22:54 »

Про семафор это скорее были мысли в слух...
"wait" делает он сам при попытке захватить ресурс сверх лимита.
« Последнее редактирование: Август 25, 2011, 22:58 от BRE » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #4 : Август 25, 2011, 23:00 »

Цитировать
Про семафор это скорее были мысли в слух...

аааа...

Цитировать
wait делает он сам при попытке захватить ресурс сверх лимита.

это я понимаю, поэтому с семафорами тоже ерунда получается - он не может остановиться до тех пор, пока ДВА ресурса не освободятся, он побежит дальше, как только освободится один
Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #5 : Август 25, 2011, 23:09 »

Основной поток:
Код
C++ (Qt)
QMutexLocker locker( &m );
while( numThread > 0 )
w.wait( &m );
 

Изначально numThread = 2, каждый поток при завершении должен сделать декремент под защитой мутекса m, ну и wakeOne.

« Последнее редактирование: Август 25, 2011, 23:12 от BRE » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #6 : Август 25, 2011, 23:19 »

Основной поток:
Код
C++ (Qt)
QMutexLocker locker( &m );
while( numThread > 0 )
w.wait( &m );
 

Изначально numThread = 2, каждый поток при завершении должен сделать декремент под защитой мутекса m, ну и wakeOne.



надо разобраться...
« Последнее редактирование: Август 25, 2011, 23:23 от Гурман » Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #7 : Август 25, 2011, 23:22 »

Так тут никакая остановка главного потока не подойдет, т.к. нужно постоянно крутить очередь событий для обработки сигналов.  Строит глазки
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #8 : Август 25, 2011, 23:24 »

QWaitCondition на очередь событий не влияет
Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #9 : Август 25, 2011, 23:25 »

Влияет, wait поток останавливает! Иначе в нем смысла не было бы. Улыбающийся
« Последнее редактирование: Август 25, 2011, 23:28 от BRE » Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #10 : Август 25, 2011, 23:35 »

он останавливает только главный поток, но не обработку событий, иначе у меня не работали бы "двунаправленные сокет-слоты", то есть, "сигналы с возвратом значения", вот такие:

Код:
void class::sender( int somevalue )
{
    QMutex mutex;
    mutex.lock();
    emit send( somevalue );  // послали другому объекту сигнал
    waiter.wait( &mutex, 1000 ); // и ждем его ответа
    mutex.unlock();
    process( 0.0 );
}

// это слот, в который другой объект присылает ответ
void class::receiver( float returnedvalue ) // SLOT
{
    waiter.wakeAll();
    process( returnedvalue );
}
кстати, тогда и таймер бы не работал у самого wait, и интерфейс бы блокировался, но этого не происходит
« Последнее редактирование: Август 25, 2011, 23:45 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #11 : Август 25, 2011, 23:40 »

а зачем там QMutexLocker ? какой в нем тут смысл?
Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #12 : Август 25, 2011, 23:44 »

wait таймеры не использует.
А зачем ты у wait таймаут используешь? А если его убрать?
Ну и твой кусок кода ничего не показывает, ни очередь событий, ни "сигналы с возвратом значений".

Главное! wait останавливает поток, наглухо. Останавливается все, включая очередь сообщений. Это то, для чего он предназначен. Подмигивающий
Записан
BRE
Гость
« Ответ #13 : Август 25, 2011, 23:45 »

а зачем там QMutexLocker ? какой в нем тут смысл?
Безопасно залочить мьютекс.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

Qt 2.2, 3.3, 4.5, 4,7, 4.8, 5.3, 5.6, 5.9, 5.12


Просмотр профиля
« Ответ #14 : Август 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(), который в основном цикле ожидания используется

Цитировать
Безопасно залочить мьютекс.

а какая может быть опасность?
« Последнее редактирование: Август 25, 2011, 23:59 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.432 секунд. Запросов: 22.