Это правильный способ использования QThread?
Я смотрю на некоторые проекты GitHub, где один из них сделал UDPlink следующим образом, сначала это подкласс QThread, чтобы создать класс UDPLink:public QThread
и его конструктор и деконструктор похож на:
UDPLink::UDPLink(UDPConfiguration* config)
: _socket(NULL)
, _connectState(false)
{
Q_ASSERT(config != NULL);
_config = config;
_config->setLink(this);
// We're doing it wrong - because the Qt folks got the API wrong:
// http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
moveToThread(this);
// Set unique ID and add link to the list of links
_id = getNextLinkId();
qDebug() << "UDP Created " << _config->name();
}
UDPLink::~UDPLink()
{
// Disconnect link from configuration
_config->setLink(NULL);
_disconnect();
// Tell the thread to exit
quit();
// Wait for it to exit
wait();
this->deleteLater();
}
Хотя код компилируется и работает, но мне интересно, будет ли этот способ использования QThread правильным?
2 ответа
Как рекомендует разработчик Qt, указанный вами код не является правильным способом использования QThread.
Рекомендуемый способ предлагается здесь.
Пример кода из поста.
Producer producer;
Consumer consumer;
producer.connect(&consumer, SIGNAL(consumed()), SLOT(produce()));
consumer.connect(&producer, SIGNAL(produced(QByteArray *)), SLOT(consume(QByteArray *)));
// they both get their own thread
QThread producerThread;
producer.moveToThread(&producerThread);
QThread consumerThread;
consumer.moveToThread(&consumerThread);
// go!
producerThread.start();
consumerThread.start();
Документы Qt для QThread описывают два способа создания потоков с помощью QThread. Подклассификация QThread была единственным способом изначально использовать QThread. Чтобы использовать QThread таким способом, переопределите метод run, который является методом QThread, который выполняется в новом потоке. QThread следует рассматривать как менеджер потоков, а не объект, который выполняется в отдельном потоке. Из документов:
Важно помнить, что экземпляр QThread живет в старом потоке, который его создал, а не в новом потоке, который вызывает run(). Это означает, что все слоты QThread в очереди будут выполняться в старом потоке. Таким образом, разработчик, желающий вызывать слоты в новом потоке, должен использовать подход рабочий объект; новые слоты не должны быть реализованы непосредственно в подклассе QThread.
При создании подкласса QThread имейте в виду, что конструктор выполняется в старом потоке, в то время как run () выполняется в новом потоке. Если переменная-член доступна из обеих функций, то переменная доступна из двух разных потоков. Убедитесь, что это безопасно.
Именно потому, что QThread является классом диспетчера потоков, было создано решение для перемещения объектов в потоки. Комментарий в предоставленном вами коде делает заявление об этом изменении, так как в этой статье говорится, что moveToThread (this) не является хорошей практикой.
Создание объекта и его перемещение в поток и подкласс QThread являются допустимыми подходами к созданию потоков в Qt, как теперь ясно указано в документации. Использование подхода "рабочий-объект" имеет преимущество, если вы хотите использовать соединения сигнал / слот через границы потоков: рабочий объект будет иметь свои слоты в том потоке, в который он перемещен.