2012-06-28 4 views
3

В течение последних нескольких дней я использовал новый предпочтительный подход для использования QThread без подкласса QThread. У меня возникла проблема, когда я пытаюсь отключить набор потоков, которые я создал. Я регулярно получаю сообщение «Разрушенный пока поток по-прежнему работает» (если я работаю в режиме отладки, я также получаю диалоговое окно «Сегментация»). Мой код очень прост, и я попытался следовать примерам, которые я смог найти в Интернете.Qthread - проблема с отключением нитей

Моя основная настройка такова: у меня есть простой класс, который я хочу запустить в отдельном потоке; на самом деле, я хочу запустить 5 экземпляров этого класса, каждый в отдельном потоке. У меня есть простой диалог с кнопкой для запуска каждого потока и кнопка для остановки каждого потока (10 кнопок). Когда я нажимаю одну из кнопок «Пуск», создается новый экземпляр тестового класса, создается новый QThread, вызывается movetothread, чтобы получить объект тестового класса в поток ... также, поскольку у меня есть пара других участников тестового класса, которые необходимо переместить в поток, я вызываю movetothread несколько дополнительных раз с этими другими элементами. Обратите внимание, что один из этих элементов - это QUdpSocket, и хотя это может и не иметь смысла, я хотел убедиться, что сокеты могут быть перемещены в отдельный поток таким образом ... Я не тестировал использование сокета в нить в этот момент.

Запуск нитей, похоже, работает нормально. Когда я использую команду linux top, чтобы увидеть, были ли потоки созданы и запущены, они отображаются, как ожидалось.

Проблема возникает, когда я начинаю останавливать потоки. Я случайным образом (или, как представляется, случайным) получает ошибку, описанную выше.

Класс, который должен работать в отдельном потоке:

// Declaration 
class TestClass : public QObject 
{ 
Q_OBJECT 
public: 
explicit TestClass(QObject *parent = 0); 
QTimer m_workTimer; 
QUdpSocket m_socket; 

Q_SIGNALS: 
void finished(); 

public Q_SLOTS: 
void start(); 
void stop(); 
void doWork(); 

}; 

// Implementation 
TestClass::TestClass(QObject *parent) : 
QObject(parent) 
{ 

} 

void TestClass::start() 
{ 
    connect(&m_workTimer, SIGNAL(timeout()),this,SLOT(doWork())); 
    m_workTimer.start(50); 
} 

void TestClass::stop() 
{ 
    m_workTimer.stop(); 
    emit finished(); 
} 

void TestClass::doWork() 
{ 
int j; 
for(int i = 0; i<10000; i++) 
    { 
    j = i; 
    } 
} 

Внутри моего основного приложения, код называется, чтобы начать первый поток (аналогичный код существует для каждого из других потоков):

mp_thread1 = new QThread(); 
mp_testClass1 = new TestClass(); 
mp_testClass1->moveToThread(mp_thread1); 
mp_testClass1->m_socket.moveToThread(mp_thread1); 
mp_testClass1->m_workTimer.moveToThread(mp_thread1); 

connect(mp_thread1, SIGNAL(started()), mp_testClass1, SLOT(start())); 
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(quit())); 
connect(mp_testClass1, SIGNAL(finished()), mp_testClass1, SLOT(deleteLater())); 
connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater())); 
connect(this,SIGNAL(stop1()),mp_testClass1,SLOT(stop())); 

mp_thread1->start(); 

Также в моем основном приложении этот код вызывается, когда нажата кнопка остановки для конкретной нити (в этом случае нить 1):

emit stop1(); 

Иногда кажется, что потоки остановлены и уничтожены без проблем. В других случаях я получаю ошибку, описанную выше.

Любое руководство будет принята с благодарностью.

Спасибо,

Bryan

ответ

4

http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

«Наконец, для предотвращения неприятных аварий, потому что поток не полностью закрыт еще, когда он удаляется, мы подключаем законченное() из (не рабочий!) в свой собственный слот deleteLater(). Это приведет к удалению потока только после полного его завершения ».

Пожалуйста, попробуйте заменить:

connect(mp_testClass1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater())); 

с:

connect(mp_thread1, SIGNAL(finished()), mp_thread1, SLOT(deleteLater())); 
Смежные вопросы