Это правильный способ использования 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 страница документации

Именно потому, что QThread является классом диспетчера потоков, было создано решение для перемещения объектов в потоки. Комментарий в предоставленном вами коде делает заявление об этом изменении, так как в этой статье говорится, что moveToThread (this) не является хорошей практикой.

Создание объекта и его перемещение в поток и подкласс QThread являются допустимыми подходами к созданию потоков в Qt, как теперь ясно указано в документации. Использование подхода "рабочий-объект" имеет преимущество, если вы хотите использовать соединения сигнал / слот через границы потоков: рабочий объект будет иметь свои слоты в том потоке, в который он перемещен.

Другие вопросы по тегам