Qt moveToThread работает только в первый раз

#c #qt #qthread

#c #qt #qthread

Вопрос:

Я создаю приложение, выполняющее бесконечную задачу, поэтому я решил управлять им с помощью QThread. При определенных условиях этот поток должен создавать временный therad для выполнения некоторых вычислений. Проблема в том, что это работает только в первый раз, в то время как во второй раз я получаю эту ошибку:

 QObject::moveToThread: Current thread (0xd29078) is not the object's thread (0x6e000df0).
Cannot move to target thread (0x6e002c68)
  

В основном я инициализировал класс и переместил его в QThread.

 AccelerometerBuffer accBuffer;
QThread *accelerometerThread = new QThread;
accelerometerThread->setObjectName("AccelerometerThread");
accelerometerThread->setParent(amp;accBuffer);
accBuffer.moveToThread(accelerometerThread);
QObject::connect(accelerometerThread,SIGNAL(started()),amp;accBuffer,SLOT(readAccelerationData()));
QObject::connect(accelerometerThread,SIGNAL(finished()),accelerometerThread,SLOT(deleteLater()));
accelerometerThread->start();
  

В readAccelerationData после условия я должен вызвать другой СЛОТ (SaveData()) в классе AccelerometerBuffer, и поэтому временный поток должен быть порожден accelerometerThread.

 if(condition){
    QThread* thread = new QThread;
    QThread::currentThread()->moveToThread(thread);
    connect(thread,SIGNAL(started()),QThread::currentThread()->parent(),SLOT(saveData()));
    connect(thread,SIGNAL(finished()),thread,SLOT(deleteLater()));
    thread->start();
}
  

При первом возникновении условия все работает нормально, SaveData выполняется правильно.
В следующих случаях вместо этого я получаю ошибку и не понимаю причины.

Ответ №1:

Вы можете только moveToThread из потока-владельца. Как только вы перейдете в другой поток, тот же вызов больше не сможет ничего сделать.

Из https://doc.qt.io/qt-5/qobject.html#moveToThread

Предупреждение: Эта функция не потокобезопасна; текущий поток должен совпадать с привязкой к текущему потоку. Другими словами, эта функция может только «переместить» объект из текущего потока в другой поток, она не может «вытащить» объект из любого произвольного потока в текущий поток.

Комментарии:

1. Итак, во второй раз поток accelerometerThread «живет» в контексте временного потока и не может выполнить другой moveToThread , верно?

2. Не совсем уверен, что ты имеешь в виду @Cristiano

3. После перемещения accelerometerThread во временный поток, и, как вы сказали, текущий поток должен совпадать с привязкой текущего потока, но я изменил его, и поэтому я получаю ошибку. Это мое главное сомнение