Бесконечный цикл в методе объекта в отдельном потоке

Есть некоторый объект, перемещаем его в поток moveToThread(), вызываем в нем некоторый метод

foo()
{
    while (true)
       {}
}

Что будет если потом вызвать из основного потока другой метод bar() перемещенного объекта?


Ответы (4 шт):

Автор решения: Матвей Суслов

Если Вы передаёте ваш объект по ссылке(или указателем), то изменения в одном потоке повлияют на него и в другом, а если вы передаёте объект копированием, то в этом потоке уже будет КОПИЯ объекта, которая является другим объектом, и его изменение никак не повлияет на изначальный объект.

→ Ссылка
Автор решения: eri

Если вызвать метод как функцию - то он выполнится в текущем потоке. Если выполнить его как слот - то он выполнится в том, если не указать это явно.

→ Ссылка
Автор решения: Sergey Tatarincev

Если у вас в потоке будет бесконечный цикл, перестанет работать эвентлуп потока (это и события и сигналы). Использование бесконечного цикла в общем и целом не приветствуется. В идеале лучше перейти к работе машины с конечными состояниями (QStateMachine). Но если уж так сильно надо, то внутри вашего цикла "пинайте" очередь сообщений.

foo()
{
    while (true)
       {
        // ...
        qApp->processEvents();
        // ...
        }

}

кроме того в концепции Qt несколько коряво будет выглядеть "вызвать из основного потока другой метод bar() перемещенного объекта". Логичнее оформить это как сигнал-слот.

→ Ссылка
Автор решения: maestro

Метод moveToThread влияет только на то, в каком потоке будут вызваны слоты и обработчики событий. Например, если есть SomeClass : public QObject, то есть следующие варианты его поведения при помещении в отдельный поток.

SomeClass *a = new SomeClass;
a->moveToThread(someThread);
a->foo(); //Этот метод выполнится в текущем потоке.
QObject::connect(this, someSignal, a, &SomeClass::barSlot); //при генерации сигнала someSignal слот barSlot будет выполнен в потоке someThread
QObject::connect(this, someSignal, a, &SomeClass::barSlot, Qt::QueuedConection);//при генерации сигнала someSignal слот barSlot выполнится в потоке someThread
QObject::connect(this, someSignal, a, &SomeClass::barSlot, Qt::DirectConection);//при генерации сигнала someSignal слот barSlot выполнится в текущем потоке.
QObject::connect(this, someSignal, a, &SomeClass::barSlot, Qt::BlockingQueuedConnection);//при генерации сигнала someSignal слот barSlot выполнится в потоке someThread, при этом текущий поток будет приостановлен до окончания выполнения слота.

Те же принципы относятся к методу QMetaObject::invokeMethod.

QMetaObject::invokeMethod(a, "barSlot", Qt::QueuedConnection, Q_ARG(arg1), Q_ARG(arg2));
→ Ссылка