QThread для неопределенного жизненного цикла, не связанного с петлейC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 QThread для неопределенного жизненного цикла, не связанного с петлей

Сообщение Anonymous »

Я понимаю, как qthread должен использоваться концептуально, с чем-то похожим на следующее

Код: Выделить всё

MyWorker *worker = new MyWorker();
QThread *thread = new QThread();
worker->moveToThread(thread);
connect(thread, SIGNAL(started()), worker, SLOT(doWork()));
connect(worker, SIGNAL(done()), thread, SLOT(quit()));
connect(worker, SIGNAL(done()), worker, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
thread->start();
, который выполнит метод dowork () в MyWorker в потоке , останавливая поток и выполняя очистку памяти после объявления работника это выполнено через DODE () . Вот как я видел все примеры, и он действительно кажется ориентированным на то, что работник выполняет операцию в отдельном потоке < /em> типа использования.

Код: Выделить всё

Qt::AutoConnection
будет использовать qt :: directconnection , если объекты сигнала и слот живут в одном и том же потоке
[*]

Код: Выделить всё

Qt::AutoConnection
будет использовать qt :: queuedconnection , если объекты сигнала и слот живут в другом потоке
[*]

Код: Выделить всё

Qt::DirectConnection
выполнит слот назначения в том же потоке, что и Source Signal
[*]

Код: Выделить всё

Qt::QueuedConnection
будет стоять в очереди сигнал так, чтобы он (в конце концов) был выполнен в цикле событий в потоке слота назначения
[*]

Код: Выделить всё

moveToThread()
"relocates" an object from its current thread into the specified one
[*]A QThread will remain active (regardless of the objects within) until QThread::quit() is called (which is why the connect to SLOT(quit()) in the above code example is so important

So Это приводит меня к двум вопросам для возможного варианта использования, который, по -видимому, немного поступает против формулы назначения QThread , и которую я действительно не смог найти обсуждаемой. PrettyPrint-Override ">

Код: Выделить всё

MyWorker *worker = new MyWorker();
QThread *workerThread = new QThread();
worker->moveToThread(workerThread);
connect(workerThread, SIGNAL(finished()), worker, SLOT(deleteLater()));
connect(workerThread, SIGNAL(finished(), thread, SLOT(deleteLater()));
workerThread->start();
В вышеперечисленном нет выделенного «выполнения» слота/метода в MyWorker , что означает, что он будет выполнять любые слоты триггеров в потоке (при условии, что соединение было выполнено с использованием qt :: autoconnection или qt :: queuedconnection , конечно). Таким образом, если в другом месте в коде я должен был сделать: < /p>

Код: Выделить всё

MyTrigger trigger;
connect(&trigger, SIGNAL(triggered()), worker, SLOT(doSomething()));
Тогда в любое время триггер издает сигнал запускаемой () , работник выполнит dosomhething () слот в рабочем рабочем состоянии , а не любой поток, который является Trigger , к которому принадлежит? Таким образом, обработка слотов будет быть многопоточной, без того, чтобы в потоке был выполнен явный элемент Dowork () . Вопрос ... < /p>
Вопрос 2 - В каком потоке создан объект? Продолжая из приведенного выше примера, допустим, что я хочу заменить MyWorker на какие -то более широкие возможности, где я хочу, чтобы вся возможность работать в этом отдельном потоке. Я думаю о том, чтобы по существу расширить приведенную выше идею, но вместо того, чтобы использовать один класс, используя серию классов, которые создаются из центрального класса. Я думаю, это что-то вроде < /p>

Код: Выделить всё

class MyCapability: public QObject {
Q_OBJECT

public:
MyOtherWorker* getOtherWorker() {
return worker2;
}

public slots:
void setup() {
worker1 = new MyWorker();
worker2 = new MyOtherWorker();

connect(worker1, SIGNAL(something()), worker2, SLOT(other()));
}

void doSomething() {
worker1->doSomething();
}

private:
MyWorker *worker1;
MyOtherWorker *worker2;
};

MyCapability *capability = new MyCapability();
QThread *capabilityThread = new QThread();
capability->moveToThread(capabilityThread);
connect(capabilityThread, SIGNAL(started()), capability, SLOT(setup()));
connect(capabilityThread, SIGNAL(finished()), capability, SLOT(deleteLater()));
connect(capabilityThread, SIGNAL(finished(), thread, SLOT(deleteLater()));
capabilityThread->start();
< /code>
Так: < /p>
[list]
[*]capability
будет жить в возможностях wapabilityThread
[*] Поскольку MyCapability :: setup () называется внутри capabilityThread Все, что будет принадлежать, будет принадлежать CapabilityThread , а также
[*]

Код: Выделить всё

worker1::something()
подключается к Worker2 :: ower () как qt :: directconnection , поскольку они находятся в одном и том же потоке
[/list]
Когда это используется от внешнего

Код: Выделить всё

MyTrigger trigger;
connect(&trigger, SIGNAL(doSomethingTrigger()), capability, SLOT(doSomething()));
connect(&trigger, SIGNAL(doOtherTrigger()), capability->getOtherWorker(), SLOT(other()));
< /code>
trigger
будет подключаться через qt :: queueconnection как способность , coder1 и работник 2 все живет в рамках возможностей wapifabureThread (при условии, что триггер в другой). Такой, что остальная часть приложения может в значительной степени игнорировать то, в каком потоке он может (или не может) жить, но которая будет выполнять свою обработку/выполнение в своем выделенном потоке с помощью сигналов/слотов безопасным и надежным образом. правильно.
Является ли мое понимание на этих двух фронтах правильно? Из каких ошибочных предположений я работаю?
Спасибо!

Подробнее здесь: https://stackoverflow.com/questions/795 ... -lifecycle
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»