2015-03-13 4 views
0

Я смотрю на некоторых GitHub проектах, где один из них сделал в UDPlink следующим образом, сначала подкласс QThread создать класс UDPLink:public QThread и его конструктор и Разрушитель, как:Правильно ли это использовать 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?

ответ

1

Как рекомендовал разработчик Qt, вы упомянули неверный способ использования QThread.

Рекомендуемый способ предлагается here.

Образец кода из сообщения.

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(); 
3

Документы Qt для QThread описывают два способа обработки потоков с помощью QThread. Подкласс QThread был единственным способом использовать QThread изначально. Чтобы использовать QThread таким образом, переопределите метод run, который является методом QThread, который работает в новом потоке. QThread следует рассматривать как диспетчер потоков, а не объект, который выполняется на отдельном потоке. Из документов:

Важно помнить, что экземпляр QThread живет в старом потоке, реализованного его, а не в новом потоке, который вызывает запуск(). Это означает, что все очереди в QThread будут выполняться в старом потоке . Таким образом, разработчик, который хочет вызывать слоты в новом потоке , должен использовать подход «рабочий-объект»; новые слоты не должны быть , реализованные непосредственно в подклассу QThread.

При подклассификации QThread имейте в виду, что конструктор выполняет в старом потоке, а run() выполняется в новом потоке. Если переменная-член получает доступ к обеим функциям, тогда переменная имеет значение , доступ к которому осуществляется из двух разных потоков. Убедитесь, что это безопасно.

QThread documentation page

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

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