Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: akaMDA от Май 30, 2012, 11:35



Название: Сигналы - слоты между потоками
Отправлено: akaMDA от Май 30, 2012, 11:35
Имеется класс, унаследованниый от Qthread. в run() запускается exec(). В этом классе имеется слот. При создании объекта данного класса производится коннект сигнала из главного потока придожения и моего потока. При посылке данного сигнала получается, что слот отрабатывается в главном потоке, а не в созданном. Определили это вызываю currentThreadID(). В конструкторе главного потока она совпадает со значением в слоте. А в функции run() моего потока TID другой.  Что я не правильно делаю? 


Название: Re: Сигналы - слоты между потоками
Отправлено: mutineer от Май 30, 2012, 11:40
неправильно ты считаешь, что потомок QThread живет в управляемом им потоке. Не наследуй QThread, а создай новый объект (наследник QObject) со слотом, создай QThread, запусти QThread и мувни в него свой объект - все будет работать как надо.
Поищи по форуму и по гуглу - много объяснений хороших есть


Название: Re: Сигналы - слоты между потоками
Отправлено: Пантер от Май 30, 2012, 11:43
Вот эту тему почитай http://www.prog.org.ru/topic_17090_0.html


Название: Re: Сигналы - слоты между потоками
Отправлено: navrocky от Май 30, 2012, 11:48
Избитая тема. Надо весь функционал и сигналы перенести в отдельного наследника от QObject и его создавать в методе run().

Второй менее правильный метод - перенести поток самого в себя: QThread::QThread() {moveToThread(this);}
Но я бы не стал его использовать, т.к. это не документировано и чую проблему в вызове сигналов самого потока (finished(), started(), terminated()). Хотя интернет завален этим советом.

Вот недавняя тема здесь: http://www.prog.org.ru/topic_21333_0.html


Название: Re: Сигналы - слоты между потоками
Отправлено: Bepec от Май 30, 2012, 11:55
navrocky, эта тема закрыта. MoveToThread никаких проблем не вызывает. Просто другое архитектурное решение, менее гибкое, но более простое.

А создателю темы советую:
1) привести код программы.
2) спросить совета.
3) выложить минимально компилируемый пример в архиве(аттач к сообщению)

PS я сам начал понимать концепции потоков и междупоточных соединений в Qt после двухдневного разбирательства с знающим человеком :)


Название: Re: Сигналы - слоты между потоками
Отправлено: akaMDA от Май 30, 2012, 12:34
Вот констутктор
Код:
threadFormatDetector::threadFormatDetector(formatDetectorEngineRoot* _formatDetector, QObject *parent) :
    QThread(parent)
{
    std::cout <<"jobProcessing1 " << (int)this->currentThreadId() << std::endl;
    this->moveToThread(this);
    std::cout <<"jobProcessing2 " << (int)this->currentThreadId() << std::endl;
    this->formatDetector = _formatDetector;
}

Значение this->currentThreadId() не изменяется! А в run() оно другое.


Название: Re: Сигналы - слоты между потоками
Отправлено: mutineer от Май 30, 2012, 12:42
Значение this->currentThreadId() не изменяется! А в run() оно другое.

Оно тут и не изменится - метод не может вот так вот посреди выполнения перейти в другой тред


Название: Re: Сигналы - слоты между потоками
Отправлено: Bepec от Май 30, 2012, 12:56
Чёт я сеня добрый - наверно велосипед влияет :) Я на нём йежжу и добрею с каждым днём.

Потоки:
1) Основной (гуишный)
2) QThread(который ты создаёшь)

QThread - создаётся он в потоке родителя (основной).
Конструктор выполняется в потоке родителя (основной).

Как только ты вызываешь метод QThread::start() - появляется поток №2 (QThread(который ты создаёшь) ).
И в нём (QThread(который ты создаёшь) )  начинается выполнение метода run(). И он уже находится во втором, независимом от основного, потоке!!!

А вызываемые через сигналы методы, будут вызываться в зависимости от типа connect(). Пятый параметр.

PS Вроде так, если ошибаюсь меня поправят, чему я буду только рад :)



Название: Re: Сигналы - слоты между потоками
Отправлено: Пантер от Май 30, 2012, 13:18
Чёт я сеня добрый - наверно велосипед влияет :)

Наконец сидение на него прикрутил? :D


Название: Re: Сигналы - слоты между потоками
Отправлено: Bepec от Май 30, 2012, 13:26
Неа. Просто передний переключатель протёр насквозь цепью, да ещё и погода была 11 градусов дня четыре уж подряд.

Если нет кожанки, краг, да кепки аэродрома - фиг поездишь. Замёрзаешь на 30 км :D


Название: Re: Сигналы - слоты между потоками
Отправлено: Пантер от Май 30, 2012, 13:34
Неа. Просто передний переключатель протёр насквозь цепью, да ещё и погода была 11 градусов дня четыре уж подряд.

Если нет кожанки, краг, да кепки аэродрома - фиг поездишь. Замёрзаешь на 30 км :D
Это я про анекдот:
Цитировать
Почтальон Печкин: «Это я раньше почему такой злой был? Потому, что у меня седла на велосипеде не было.»


Название: Re: Сигналы - слоты между потоками
Отправлено: Bepec от Май 30, 2012, 13:47
:D


Название: Re: Сигналы - слоты между потоками
Отправлено: DmitryM от Май 30, 2012, 15:26
Второй менее правильный метод - перенести поток самого в себя: QThread::QThread() {moveToThread(this);}
Слот это обычный метод, а значит имею полное право вызвать явно!


Название: Re: Сигналы - слоты между потоками
Отправлено: Пантер от Май 30, 2012, 15:32
Второй менее правильный метод - перенести поток самого в себя: QThread::QThread() {moveToThread(this);}
Слот это обычный метод, а значит имею полное право вызвать явно!
Уверен? Если объект в другом треде, то вызывая явно слот огребешь проблем.


Название: Re: Сигналы - слоты между потоками
Отправлено: DmitryM от Май 30, 2012, 15:43
Уверен?
Не уверен, а так написано в документации.
Цитировать
A slot is called when a signal connected to it is emitted. Slots are normal C++ functions and can be called normally; their only special feature is that signals can be connected to them.

Since slots are normal member functions, they follow the normal C++ rules when called directly. However, as slots, they can be invoked by any component, regardless of its access level, via a signal-slot connection. This means that a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.

Если объект в другом треде, то вызывая явно слот огребешь проблем.
Если будешь использовать STL контейнер в разных тредах, то так же отгребешь проблем при добавление/удаление/модификации. Или думать о thread-safety не нужно?


Название: Re: Сигналы - слоты между потоками
Отправлено: Bepec от Май 30, 2012, 15:53
Если одним потоком, то не стоит.
Если 2 и более - пара мутексов и всё ОК.


Название: Re: Сигналы - слоты между потоками
Отправлено: Igors от Май 30, 2012, 15:57
Если будешь использовать STL контейнер в разных тредах, то так же отгребешь проблем при добавление/удаление/модификации.
И не STL (напр Qt контейнер) - тоже