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

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

Страниц: 1 2 [3] 4   Вниз
  Печать  
Автор Тема: QThread, как с ним работать, где почитать подробно?  (Прочитано 32830 раз)
BRE
Гость
« Ответ #30 : Март 30, 2010, 20:19 »

Цитировать
как всетаки поток запускается? thread->run()?
processThread()->run();
Смотри что происходит при этом:
Вызывается метод run в главном потоке;
Вызывается start, при этом создается новый поток в котором начинает выполняться метод run;
После отработки start продолжает выполняться run в главном потоке (DataProcessor->Process());
Выполняется DataProcessor->Process() в дочернем потоке.

Поэтому у тебя GUI и останавливается.

Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #31 : Март 31, 2010, 06:55 »

Цитировать
После отработки start продолжает выполняться run в главном потоке (DataProcessor->Process())

по коду в главном потоке вызова DataProcessor->Process() не должно происходить, поскольку start у меня рекурсивно вызывал run, сам повторно не выполнялся, так как уже выполнился, и только после этого начинал выполняться Process()

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

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #32 : Март 31, 2010, 07:46 »

по коду в главном потоке вызова DataProcessor->Process() не должно происходить, поскольку start у меня рекурсивно вызывал run, сам повторно не выполнялся, так как уже выполнился, и только после этого начинал выполняться Process()
start создает контекст дочерней нити и в нем заново запускает run. В контексте дочернего потока start сразу выходит и запускает Process, но в главном потоке управление получает следующая строка после start и соответственно запускается свой Process.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #33 : Март 31, 2010, 08:47 »

да, так и есть Process() запускался дважды

заработало, но только с Qt::BlockingQueuedConnection, если просто Qt::QueuedConnection то интерфейс все равно не работает, хотя строки выводятся

теперь такой вопрос: QThread::isRunning () is thread-safe? можно его вызывать из главной нити, чтобы определить выполняется вторая, или уже завершилась?
« Последнее редактирование: Март 31, 2010, 08:51 от Гурман » Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #34 : Март 31, 2010, 08:49 »

заработало, но только с Qt::BlockingQueuedConnection, если просто Qt::QueuedConnection то интерфейс все равно не работает, хотя строки выводятся
Покажи побольше кода.
Тяжело телепатировать.  Подмигивающий
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #35 : Март 31, 2010, 08:54 »

Цитировать
Покажи побольше кода.

какого? всего? десятки тысяч строк... Смеющийся

- убрал вызов start() внутри run()
- заменил вызов run() на start() в главной нити
- убрал комментарии при соединении объектов, получилось

Код:
	connect( this, SIGNAL(sigConsoleMessage(QString)), pMainWindow, SLOT(slMessage(QString)), Qt::QueuedConnection);

работает почти правильно, порождается один процесс обработки (вчера точно было 2, я видел вывод обоих, и не понимал, откуда берется второй), но интерфейс блокирован, заменяю на Qt::BlockingQueuedConnection - все работает

« Последнее редактирование: Март 31, 2010, 08:56 от Гурман » Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #36 : Март 31, 2010, 09:05 »

Нее, весь не надо...

Покажи что за объект DataProcessor, как описан его класс, как он создается, хотя бы примерно что находиться в методе Process, где вызывается thread_stream?
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #37 : Март 31, 2010, 09:16 »

это большой объект, он связан с данными, построенными в главной нити, но конкретно метод Process вызывает библиотеку, написанную на С, и там производится обработка данных

Код:
bool SomeClass::Process()
{
    // здесь сначала некоторые проверки значений полей класса SomeClass, никаких внешних обращений
    return execute( FALSE );  // это функция на С
}

создается объект в главной нити, этот класс никого сам не наследует, но его наследует один из классов, работающих в главной нити, причем потомок напрямую связан с Qt, и занимается отрисовкой обрабатываемых данных

далее в объекте класса SomeClass, в его методах, в библиотеке на С, никакие классы Qt не вызываются и не используются, гарантированно, этот класс и дальнейшая обработка ранее отлажены без использования Qt, единственная связь с Qt только в выдаче сообщений во время работы второй нити, она через функцию-хук thread_stream( char* msg )

на самом деле, перед выполнением , заменяется точка входа в функцию выдачи сообщений, которую вызывает С-библиотека, потом она восстанавливается

Код:
void ProcessThread::run()
{
messasge_function = thread_stream; // ее код был ранее
        DataProcessor->Process();
messasge_function = print_stream;
}

где message_function глобальный extern "C" указатель на функцию, print_stream - указатель на функцию, которая производит выдачу сообщений, когда вторая нить не активна

сейчас гарантировано, что во время выполнения второй нити, сообщения выдаваться не могут

возможно есть смысл вызывать extern "C" int execute() прямо из run(), правда тогда придется продублировать поля из SomeClass, поскольку организовывать его взаимодействие с ProcessThread никак нельзя, SomeClass должен остаться Qt-независимым

« Последнее редактирование: Март 31, 2010, 09:25 от Гурман » Записан

2^7-1 == 127, задумайтесь...
BRE
Гость
« Ответ #38 : Март 31, 2010, 09:23 »

К объекту DataProcessor кто-то еще обращается из главного потока?
Какие-то объекты синхронизации используются?
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #39 : Март 31, 2010, 09:29 »

Цитировать
К объекту DataProcessor кто-то еще обращается из главного потока?

нет

Цитировать
Какие-то объекты синхронизации используются?

нет

во время выполнения второй нити, этот объект вообще не затрагивается никем, модифицировать его запрещено, а читать незачем, С-библиотеке он не нужен, она работает со структурами данных (таблицами), которые ранее строятся главной нитью по данным из этого объекта
« Последнее редактирование: Март 31, 2010, 09:32 от Гурман » Записан

2^7-1 == 127, задумайтесь...
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #40 : Март 31, 2010, 10:45 »

а разве чтобы нормально работали сигналы\слоты в треде, вызов exec() не нужен?
моё имхо - надо run вообще не переобпределять, сделать слот calc() и его из мейна дергать через InvokeMathod с QueuedConnection когда надо запстить расчеты. А start() нити звать в конструкторе оной к примеру
Записан
BRE
Гость
« Ответ #41 : Март 31, 2010, 11:05 »

а разве чтобы нормально работали сигналы\слоты в треде, вызов exec() не нужен?
Для отсылки сигнала - нет, а вот для получения и вызова слота - нужен.

Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #42 : Март 31, 2010, 11:14 »

ааа, ясно, спасибо.
Записан
Гурман
Гуру общения
******
Offline Offline

Сообщений: 1442

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


Просмотр профиля
« Ответ #43 : Март 31, 2010, 11:45 »

работает пока с Blocking, потом придется вернуться, и разобраться почему просто очередь не работает, но как-то все это грустно...  Грустный

в BeOS 15 лет назад был аналогичный сигналам-слотам механизм, можно было плодить какие хочешь треды, передавать любые объекты через соединения, и уже про мутексы и семафоры с ними можно было практически не вспоминать, даже можно было напрямую методы из соседних нитей вызывать, лишь бы они одновременно не модифицировали внешние по отношению к ним данные, а обращаться на чтение сколько угодно
Записан

2^7-1 == 127, задумайтесь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #44 : Март 31, 2010, 12:22 »

Код:
	connect( this, SIGNAL(sigConsoleMessage(QString)), pMainWindow, SLOT(slMessage(QString)), Qt::QueuedConnection);
работает почти правильно, порождается один процесс обработки (вчера точно было 2, я видел вывод обоих, и не понимал, откуда берется второй), но интерфейс блокирован, заменяю на Qt::BlockingQueuedConnection - все работает
Разберитесь в каких нитках были созданы сигнал/слот (this и pMainWindow). В сложной программе проще это напечатать в консоль. Если BlockingQueuedConnection вообще работает - они были созданы в разных.

работает пока с Blocking, потом придется вернуться, и разобраться почему просто очередь не работает, но как-то все это грустно...  Грустный
Что грустно-то? Что не заработало с пол-пинка?  Улыбающийся

в BeOS 15 лет назад был аналогичный сигналам-слотам механизм, можно было плодить какие хочешь треды, передавать любые объекты через соединения, и уже про мутексы и семафоры с ними можно было практически не вспоминать, даже можно было напрямую методы из соседних нитей вызывать, лишь бы они одновременно не модифицировали внешние по отношению к ним данные, а обращаться на чтение сколько угодно
Никто не мешает читать и вызывать методы объектов созданных в др. нитках, они должны быть thread-safe - в Qt и везде. Про мутексы и семафоры вспомнить придется если пишете/читаете в разных нитках. Горести по поводу отсутствия какого-то "особенного" сервиса у Qt лишены оснований поскольку все эти вещи/понятия общие для multi-threading и для любого OC и любая библиотека может только сделать это более удобным.
Записан
Страниц: 1 2 [3] 4   Вверх
  Печать  
 
Перейти в:  


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