2013-10-15 4 views
3

Я должен начать/остановить поток при нажатии двух разных кнопок.
Пожалуйста, предложите мой код правильно или нет. Я пропустил что-то в вызове connect()?Как остановить поток - Qthread

Problem я столкнулся в том, что после вызова выхода() на моей теме, то я ждать, пока мой поток, чтобы закончить, но ждать() вызов на резьбе never returns true, и мой program is stuck in, в то время как (! M_deviceThread.wait())

Пожалуйста, предложите, как это решить?

Мой devicethread & объект работника определяется в классе MainWindow: -

QThread m_deviceThread; 
deviceThreadObject *m_deviceThreadObject; 

Основной объект устройства резьбы: -----

class deviceThreadObject : public QObject 
{ 
    Q_OBJECT 
public: 
    explicit deviceThreadObject(QObject *parent = 0); 

    /*! 
     Termination control main thread 
    */ 
    bool m_bQuit; 


signals: 

public slots: 
    void dowork(); 

}; 

deviceThreadObject конструктор объекта: -

// constructor for the deviceThreadObject 
deviceThreadObject::deviceThreadObject(QObject *parent) : 
    QObject(parent) 
{ 
    m_bQuit = false; 
} 

У меня есть основная тема m_deviceThread которая работает на кнопке st искусство нажимается: ---

void MainWindow::on_actionStart_triggered() 
{ 
    if(!b_threadAlreadyStarted) 
    { 

    m_deviceThreadObject = new deviceThreadObject; 

    // connect device thread signal to the slot 
    connect(&m_deviceThread ,SIGNAL(started()),m_deviceThreadObject,SLOT(dowork())); 

    m_deviceThreadObject->moveToThread(&m_deviceThread); 

    // Set the flag before starting slot of main thread 
    m_deviceThreadObject->m_bQuit = true; 

    m_deviceThread.start(); 

    } 
} 

Я главный поток m_deviceThread который останавливается на кнопку Стоп нажата: ---

void MainWindow::on_actionStop_triggered() 
{ 
    if(b_threadAlreadyStarted) 
    { 

     b_threadAlreadyStarted = false; 

     // get out of event loop 
     m_deviceThreadObject->m_bQuit = false; 

     m_deviceThread.quit(); 
     qDebug() << " \n quit "; 

     // wait for thread to terminate 
     while(!m_deviceThread.wait()); 

     m_deviceThreadObject->deleteLater(); 

     qDebug() << " \n finished"; 

    } 

} 

// Общий слот для устройства - резьба

void deviceThreadObject::dowork() 
{ 

    while(m_bquit) 
    { 

    // Do some work 

    } 

} 
+0

Выглядит хорошо. В чем дело? –

+0

Небезопасно использовать 'm_bquit' из обоих потоков одновременно. Вы должны охранять его с помощью мьютекса. –

+0

Я бы выпустил сигнал в поток, чтобы остановить и сделать m_bquit частным. – drescherjm

ответ

2

Я видел несколько разных способов сделать это в прошлом.

Ниже показывает, что компилятор оптимизирует код, чтобы выглядеть следующим образом:

bool quit = false; 
while(!quit) 
{ 
    // no reference to quit here or in any functions mentioned in here 
} 

мог заводятся в только навсегда петлю.

// bool quit = false 
while(true) 
{ 
    // looks the same to the compiler... 
} 

Лучшая практика, которая заставляет вас знать синхронизацию потоков и критических областей или mutexs или семафоры, чтобы обработать доступ к параметру бросить курить в качестве переменной между потоками, и завернуть его, чтобы он только доступ по одному потоку за раз. Мой предпочтительный метод заключается в использовании QMutexLocker, так как она обрабатывает хорошо с изменениями охвата, return с, break с, и т.д.

http://qt-project.org/doc/qt-5.1/qtcore/qmutexlocker.html#details

Так что ваш код получает дополнения, как это:

deviceThreadObject::deviceThreadObject(QObject *parent) : 
    QObject(parent) 
{ 
    m_mutex = new QMutex(); 
} 

void deviceThreadObject::stop() 
{ 
    QMutexLocker locker(m_mutex); 
    m_stopped = true; 
} 

void deviceThreadObject::doWork() 
{ 
    m_stopped = false; 
    while(true) 
    { 
     // The core work of your thread... 

     // Check to see if we were stopped 
     { 
      QMutexLocker locker(m_mutex); 
      if(m_stopped) 
       break; 
     }// locker goes out of scope and releases the mutex 
    } 
} 

Быстрый и грязный ярлык - использовать volatile bool. Это не рекомендуемая практика и не столь надежна для компиляторов.

Надеюсь, что помогает.

Смежные вопросы