Я хочу остановить зацикливание потока, когда сигнал был выпущен, так вот мой код
void MyThread::stopWatchingThread()
{
qDebug()<<"MyThread::stopWatchingThread()";
Keep_running=false;
qDebug()<<"MyThread::stopWatchingThread Keep_running"<<Keep_running;
...
}
void MyThread::run()
{
qDebug()<<"MyThread::run()";
qDebug()<<"MyThread::run Keep_running"<<Keep_running;
while(Keep_running)
{
...
}
qDebug()<<"MyThread::run Keep_running"<<Keep_running;
Keep_running=false;
qDebug()<<"MyThread::run Keep_running"<<Keep_running;
}
void Watcher::Init()
{
WatchingThread=new MyThread(this->L_RootToWatch);
connect(this,SIGNAL(stopmonotiring()),WatchingThread, SLOT(stopWatchingThread()));
...
}
void Watcher::StartWatching()
{
WatchingThread->start();
}
void Watcher::StopWatching()
{
emit stopmonotiring();
}
Так что все идет хорошо, но моя проблема в том, что Keep_running
никогда не получите false
значение в MyThread::run()
после излучения stopWatchingThread
так что while
петля навсегда.
Что я упустил ?
любая помощь будет оценена.
Не создавайте потоковые классы явно в Qt. Вместо этого создайте рабочий объект, переместите этот объект в QThread
затем позвоните start()
на QThread
, Вот быстрый пример:
class Worker : public QObject
{
Q_OBJECT
public:
Worker( QObject * parent = 0 )
: QObject( parent )
{}
public slots:
void doWork( ... )
{
// do work here
}
void stopMonitoring()
{
emit finished();
}
signals:
void finished();
};
int main()
{
Worker * w = new Worker();
QThread * thread = new QThread();
QObject::connect( w, SIGNAL(finished()), thread, SLOT(quit())
QObject::connect( w, SIGNAL(finished()), w, SLOT(deleteLater())
QObject::connect( thread, SIGNAL(finished()), thread, SLOT(deleteLater())
w->moveToThread( thread );
thread->start();
// some other object emits a signal connected to the 'doWork()' slot.
}
Я опустил некоторые стандартные шаблоны QApplication, но они уже есть, если вы используете Qt. Это должно начать вас.
Поскольку ваш метод run () блокируется, а цикл обработки событий никогда не вводится, слот stopWatchingThread никогда не будет вызываться. Вы должны вызвать exec () и не блокировать цикл обработки с помощью вращающегося цикла в run (). Либо так, либо поток наблюдателя напрямую вызывает stopWatchingThread, а не через соединение сигнал / слот. Я бы пошел на последнее. Тогда к keepRunning будут обращаться из нескольких потоков, поэтому вы должны защитить его с помощью QMutex, QReadWriteLock или QAtomic. (Начните с QMutex, это проще всего).
Если вы используете цикл событий в вашей теме, просто опубликуйте quit()
сигнал на объект потока.
Может быть, ваш компилятор C ++ оптимизирует операцию чтения на Keep_running
, Попробуйте объявить это как volatile
, который сообщает компилятору, что эта переменная может измениться «неожиданно», например, от других потоков или аппаратных прерываний.