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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: потоки  (Прочитано 9773 раз)
CPP11
Гость
« : Декабрь 07, 2014, 23:24 »

Доброго времени суток. В ближайшее время нужно будет написать многопоточное приложение на QT, поэтому прошу прояснить некоторые моменты...
Суть приложения - есть 2 потока - Gui и General.
Gui - отвечает за пользовательский интерфейс и принимает от системы сообщения о подключаемом оборудовании(WM_DEVICECHANGE, только windows).
General - обрабатывает команды от Gui и сигнализирует в ответ об изменениях, которые нужно отобразить, обрабатывать может очень долго, потому и выделен в отдельный поток.
Насколько я понял второй поток нужно создавать как в этой заметке:
Код:
//worker.h
class Worker : public QObject{
//...
}
//main.cpp
QThread* thread = new QThread;
Worker* worker = new Worker();
worker->moveToThread(thread);
//connect'ы
thread->start();
и пока я не уничтожу объект worker поток не завершится и будет обрабатывать сигналы. И в этой конструкции, если поток Gui отправит последовательно два сигнала, то я могу быть уверен, что другой поток обработает эти сигналы именно в этой последовательности и дополнительной синхронизации не нужно. Это верно?
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #1 : Декабрь 08, 2014, 00:44 »

и пока я не уничтожу объект worker поток не завершится и будет обрабатывать сигналы.
нет, поток не завершится, пока вы его не остановите: quit() или terminate().
И в этой конструкции, если поток Gui отправит последовательно два сигнала, то я могу быть уверен, что другой поток обработает эти сигналы именно в этой последовательности и дополнительной синхронизации не нужно. Это верно?
да, верно.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Декабрь 08, 2014, 12:17 »

если поток Gui отправит последовательно два сигнала, то я могу быть уверен, что другой поток обработает эти сигналы именно в этой последовательности и дополнительной синхронизации не нужно. Это верно?
Для только одного "отправляющего" - верно, для 2 и более - нет
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #3 : Декабрь 08, 2014, 12:19 »

если поток Gui отправит последовательно два сигнала, то я могу быть уверен, что другой поток обработает эти сигналы именно в этой последовательности и дополнительной синхронизации не нужно. Это верно?
Для только одного "отправляющего" - верно, для 2 и более - нет
Два Gui потока в Qt? Это фантастика.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #4 : Декабрь 08, 2014, 12:54 »

Два Gui потока в Qt? Это фантастика.
"Напрасно, все меняется очень быстро"  Улыбающийся C 2 и более - один их самых "кровавых" багов с которыми я имел дело
Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #5 : Декабрь 08, 2014, 13:15 »

C 2 и более - один их самых "кровавых" багов с которыми я имел дело
Что вы называете "кровавым" багом?
То что если два потока добавляют сообщения в одну очередь сообщения могут чередоваться?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Декабрь 08, 2014, 13:33 »

То что если два потока добавляют сообщения в одну очередь сообщения могут чередоваться?
Да. Псевдокод (если не ошибаюсь, в 3-й раз)
Цитировать
SendEvent(receiver, jobAbort, ...);
SendEvent(receiver, resetStatus, ...);
Это не вызывает сомнений, действительно resetStatus выполнится после jobAbort. Но это совсем не значит что resetStatus будет обрабатываться сразу после jobAbort (хотя мы их и посылали немедленно одно за другим). При 2 и более отправителях др события могут вклиниться в очередь между нашими 2-мя.. изменить контекст получателя и тогда..

Конечно, это "совсем очевидно"  Улыбающийся

« Последнее редактирование: Декабрь 08, 2014, 13:43 от Igors » Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #7 : Декабрь 08, 2014, 13:40 »

Конечно, это "совсем очевидно"  Улыбающийся
Ну, как бы, да. Улыбающийся
Очереди сообщений это все те же очереди данных.
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #8 : Декабрь 08, 2014, 13:42 »

Для только одного "отправляющего" - верно, для 2 и более - нет
пример приведите, где не верно
по моему опыту и более 10 потоков работало
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Декабрь 08, 2014, 13:48 »

пример приведите, где не верно
по моему опыту и более 10 потоков работало
И по моему тоже. Просто раз в месяц пользователь сообщал о каком-то вылете. Ну добавил логи, потом еще их расширил - возился долго. Обратите внимание на "именно в этой последовательности". Так вот, при 2 и более отправителях последовательность НЕ "именно та".
Записан
CPP11
Гость
« Ответ #10 : Декабрь 08, 2014, 19:05 »

нет, поток не завершится, пока вы его не остановите: quit() или terminate().
Значит для корректного завершения потока нужно выполнить примерно такой код:
Код:
thread->quit();
if(thread->wait(1000))
{
delete worker;
delete thread;
}
Или worker нужно сперва переместить обратно? Или он сам убьётся вместе с потоком?
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Декабрь 08, 2014, 19:14 »

Без всяких 1000 - просто thread->wait()
Записан
CPP11
Гость
« Ответ #12 : Декабрь 08, 2014, 19:29 »

Без всяких 1000 - просто thread->wait()
нет, ну 50 дней его ждать точно не нужно, если за секунду не умер, то пусть аварийно завершается Улыбающийся .
Записан
Johnik
Крякер
****
Offline Offline

Сообщений: 339


Просмотр профиля
« Ответ #13 : Декабрь 08, 2014, 19:30 »

Так вот, при 2 и более отправителях последовательность НЕ "именно та".
"кто успел тот и съел"
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Декабрь 08, 2014, 19:45 »

нет, ну 50 дней его ждать точно не нужно, если за секунду не умер, то пусть аварийно завершается Улыбающийся .
Давайте без самодеятельности, аварийное завершение - себе дороже. Единственный способ завершить thread - дать ей нормально выйти. Никуда не денется - выйдет, не надо дергаться
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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