Russian Qt Forum

Qt => Многопоточное программирование, процессы => Тема начата: alexeev от Ноябрь 20, 2013, 14:01



Название: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:01
Есть класс
Код:
class cStorage: public QObject
{
public:
    cStorage();
    ~cStorage();
    void Write(QByteArray Package);
};

В дргуом классе создаю обект, поток,  переношу объект в поток, стартую поток

Код:
Storage = new cStorage();
QThread *thread = new QThread();
Storage->moveToThread(thread);
thread->start();


и в этом же классе в которым происсходит создание вызываю метод класса Storage

Код:
 Storage->Write(Package);

Он вызывается в главном потоке а не в созданном мной? Почему так? Разве перенося объект, все его методы не будут выполняться в новом потоки? Или влияет то, что этот метод я вызываю из главного потока? Помогите разобраться пожалуйста=)


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 14:11
Все правильно, при прямой вызове метод будет выполняться в том потоке из которого вызван.

Сделайте из Write слот и вызывайте его с помощью сигнала, тогда он будет выполняться в своей нитке.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:13
Сделайте из Write слот и вызывайте его с помощью сигнала, тогда он будет выполняться в своей нитке.

Можно поподробнее, что-то ничего не понял(


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:14
Т.е вместо метода сделать слот, а на месте вызова, вызвать сигнал?


Название: Re: Объясните пожалуйста)
Отправлено: Bepec от Ноябрь 20, 2013, 14:30
Почитай про сигнал-слоты.

Да, вместо метода делаешь слот. Вместо вызова делаешь сигнал. И не забудь указать тип соединения при connect'e.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:33
Тогда понятно, щас попробую.
Qt::QueuedConnection, а зачем указывать, если в документации написано, Qt::AutoConnection   0 (по умолчанию) Тоже самое, что и DirectConnection, если источник и получатель находятся в одном и том же потоке. Тоже самое, что и QueuedConnection, если источник и получатель находятся в разных потоках. Вроде по умолчанию тоже све ок должно быть


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:45
Сделал, и укзал тип соедиенния, сигнал исходит, но переход в слот не идет, подскажиет пожалуйста почему?)

коннект так пропсиал

Код:
 Storage = new cStorage();
    QThread *thread = new QThread();
    Storage->moveToThread(thread);
    
    thread->start();

    connect(this,SIGNAL(SignalWriteToStorage(QByteArray)),Storage,SLOT(Write(QByteArray)),Qt::QueuedConnection);



Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 14:53
Теперь осталось этот сигнал (SignalWriteToStorage) инициировать. :)


Название: Re: Объясните пожалуйста)
Отправлено: _OLEGator_ от Ноябрь 20, 2013, 14:53
и макрос Q_OBJECT нужен, чтобы сигнал-слотовый механизм работал.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:54
Инициировал, и макрос добавил, это я все понимаю прекрасно


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 14:58
Инициировал, и макрос добавил, это я все понимаю прекрасно
Показывайте весь код, должен вызываться. И еще вопрос, в консоль что нибудь пишется при выполнении программы?
Наверное проще это делать через QMetaObject::invokeMethod.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 14:59
Да, простите, в классе Storage не было макроса, не знаю как мог забыть =(
Но к сожалению все это не решило моей проблемы, такое ощущение, что все равно выполнятеся в одном потоке(
Я логирую данные от внешнего устройства, и если я зажимаю окно, запись в файл прекращается ( а данные терять нельзя), в связи с этим было прияно решение создать новый поток, и преместить туда объект отвечающий за логирование. Как думаете почему может не работать?


Название: Re: Объясните пожалуйста)
Отправлено: Bepec от Ноябрь 20, 2013, 15:01
Если не соединяется, будет "ай ай ай" в дебажном выводе.
Если у вас в threde не запущен цикл обработки событий, ничего и не придёт.

Показывайте код, поможем.
Не показывайте код, не поможем. :)


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:02
и если я зажимаю окно
Не венда ли часом?


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:04
Она самая, но проект будет использоваться под linux скорее всего


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:06
Так все таки, это ощущение или все работает в одном потоке?
Добавьте отладочный вывод Qt::HANDLE QThread::currentThreadId() [static]


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:08
Ну ощущение, сложилось из того, что при зажатии запись останавливается, размер файла не изменяется, и структуры данных пропускаются, это   точно.
А вот тут можо немного поподробнее с этим не знаком(( (Я об этом Qt::HANDLE QThread::currentThreadId() [static])


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:13
Ну ощущение, сложилось из того, что при зажатии запись останавливается,
Это похоже на вендопроблему, она останавливает свою очередь событий при перетаскивании окна и с ней останавливаются всё.
Отдельная нитка должна решить проблему.

А вот тут можо немного поподробнее с этим не знаком(( (Я об этом Qt::HANDLE QThread::currentThreadId() [static])
Добавьте:
Код
C++ (Qt)
qDebug() << QThread::currentThreadId();

В главную нитку и в метод Write и увидите в каких потоках что выполняется. Если id будут одинаковые, то все выполняется в одном потоке, иначе в разных.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:22
0x1760 Main Method
0x16c8 Write Method

Id у потоков разные


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:22
Id у потоков разные
Значит нитки разные, что и требовалось. :)


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:23
Тогда, почему моя задача не решилась, я полностью был уверен что поможет =( ???


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:29
Тогда, почему моя задача не решилась, я полностью был уверен что поможет =( ???
Так а кто данные производит? Главная нитка? Тогда конечно не поможет.
Нужно весь опрос переносить в новую нитку, а не только запись.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:32
Данные с ком порта принимаются в одном классе, в другой пересылаются и обрабатываются, в котором и просиходит создание это объекта Storage.


Название: Re: Объясните пожалуйста)
Отправлено: Old от Ноябрь 20, 2013, 15:45
Данные с ком порта принимаются в одном классе, в другой пересылаются и обрабатываются, в котором и просиходит создание это объекта Storage.
Вот нужно, что бы прием был в отдельной нитке. Можно совместить их с обработкой, а можно вообще сделать одну нитку на прием, другую на обработку.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 15:52
А вы Бы не могли объяснить почему не работает? Потому что данные просто послаться не могут в класс который находится в другом потоке, т.к поток главный при зажатии окна блокируется?
Тогда действительно приедтся перенсоить в отдельный поток и получение данных и их обработку(


Название: Re: Объясните пожалуйста)
Отправлено: Bepec от Ноябрь 20, 2013, 16:40
Оконный менеджер Windows при захвате окна за заголовок блокирует поток этого окна. Т.е. поток приостанавливается. Почему и зачем - я вам не отвечу. Я сам задавал этот вопрос, но другого ответа не нашёл.

Как победить? В основном потоке только отрисовка, вся работа в других потоках.


Название: Re: Объясните пожалуйста)
Отправлено: alexeev от Ноябрь 20, 2013, 16:56
А в linux так же?


Название: Re: Объясните пожалуйста)
Отправлено: Bepec от Ноябрь 20, 2013, 17:32
Оконный менеджер Windows

Никто не жаловался, так что думаю нет, но... Всё зависит от оконного менеджера :)


Название: Re: Объясните пожалуйста)
Отправлено: GreatSnake от Ноябрь 21, 2013, 07:40
А в linux так же?
Нет, т.к. WM на X11 является отдельным приложением.


Название: Re: Объясните пожалуйста)
Отправлено: Igors от Ноябрь 21, 2013, 09:35
Как победить? В основном потоке только отрисовка, вся работа в других потоках.
А что так побеждается если рисует только главный поток?
Вот у меня сейсас открыт "Resource Monitor". Когда окно таскается, сначала появляется рамка и лишь при отпускании мыши окно передвигается. А во время драга информация в окне обновляется. Когда-то на OSX сам делал такое (несложно, через overlayWindow), не знаю, может сейчас уже в этом нет необходимости. Но что здесь должны быть стандартные решения - и к бабке не ходи, вот только мне они (пока) неизвестны  :)