2016-02-02 2 views
1

Я работаю над Qt 5.5 и создал отдельный поток, который использует сторонние библиотеки API. Эта функция Api, которая при выполнении потребляет все ресурсы и не позволяет выполнять какую-либо другую функцию в этом потоке.QT -> как убить поток, если поток потребляет все ресурсы и не разрешает выполнение слота

Этот новый поток начинается нажатием кнопки «Начать», и я просто не знаю, как остановить или убить поток, когда я нажимаю кнопку остановки. Ниже приведен пример моего примера

threadWorking = new QThread(); 
workHeavy = new WorkingHard; 

     workHeavy->moveToThread(threadWorking); 

     connect(threadWorking, SIGNAL(started()),  workHeavy,  SLOT(slotStartStream())); 
     connect(workHeavy,  SIGNAL(sigStopStream()), threadWorking, SLOT(quit())); 
     connect(workHeavy,  SIGNAL(sigStopStream()), workHeavy,  SLOT(deleteLater())); 
     connect(threadWorking, SIGNAL(finished()),  threadWorking, SLOT(deleteLater())); 

     connect(workHeavy,  SIGNAL(sigStartStream()), this, SLOT(slotTrueStreamRun() )); 
     connect(workHeavy,  SIGNAL(sigStopStream()), this, SLOT(slotFalseStreamRun())); 

     connect(this,   SIGNAL(sigMopsCamStopCmd()), workHeavy, SLOT(slotStopStream())); 
     threadWorking->start(); 

Also// void WorkingHard::slotStartStream() 
{ 
    g_main_loop_run(gloop); // this consumes all resources. 
} 
void WorkingHard::slotStopStream() 
{ 
    // clean up mess 
g_main_loop_quit(gloop); 
    gst_element_set_state (pipeline, GST_STATE_NULL); 
    // g_main_loop_quit(gloop); 
    releaseMemory(); 
} 

Прошу посоветовать мне убить нить на основе идентификатора или чего-то еще. Ясно одно: я не могу войти в поток, когда функция запущена.

Как люди предложили использовать terminate. Если я использую terminate(), мне все равно нужно освободить память, как я указал в файле slotStopStream ??

+0

Пример вашего примера далеко не полный и минимальный, если требуется. Тем не менее, исследуйте термин «аннулирование потока» и почему это проблематично. Альтернативным может быть использование другого процесса. –

+0

Вы должны показать свой рабочий цикл WorkingHard. Вот где вы должны поместить обнаружение для завершения потока, но трудно советовать, не зная, какой у вас код. – hyde

+0

Как люди предложили прекратить. Если я использую terminate(), мне все равно нужно освободить память, как я указал в функции slotStopStream ?? – samprat

ответ

0

Прошу посоветовать мне убить нить на основе id или что-то еще.

Вы не нуждаетесь в таких советах. Завершение работы потока утечки ресурсов и может оставить ваш процесс в коррумпированном состоянии - например. структуры данных кучного менеджера могут быть повреждены или другое глобальное состояние может быть повреждено. Не принудительно завершать потоки - все остальное - неопределенное поведение.

Я очень сомневаюсь, что g_main_loop_run «потребляет» все ресурсы. Ну, он занят чем-то, или ждет, когда что-то случится. В конце концов, это цикл событий. It's even documented :) Звонок g_main_loop_run ничем не отличается от звонка exec() на QEventLoop.

Вы можете позвонить по номеру g_main_loop_quit, чтобы закрыть цикл событий. Если бы это было QEventLoop, вы могли бы позвонить по нему quit из любой темы. Но я не уверен, что g_main_loop_quit является потокобезопасным, документация - это мама об этом. Увы, нам не о чем беспокоиться: мы можем вызвать его из самой рабочей нити.

Мы позвоним g_main_loop_quit из контекста цикла. Тело лямбда будет работать в рабочем потоке и вызовет петлю для выхода:

class WorkingHard : public QObject { 
    Q_OBJECT 
    GMainLoop * gloop; 
    .... 
}; 

/// This method is thread-safe 
void WorkingHard::quitLoop() { 
    auto context = g_main_loop_get_context(gloop); 
    g_main_context_invoke(context, +[](gpointer ptr) -> gboolean { 
    g_main_loop_quit((GMainLoop*)ptr); 
    return FALSE; 
    }), (gpointer)gloop); 
} 

Оператор + применяется к лямбда преобразует его в указатель на функцию. Это избавляет вас от определения автономной функции.

Чтобы закончить цикл, позвоните по номеру quitLoop из любой темы.

Обратите внимание, что если вы работаете в Linux, то QEventLoop основан на цикле событий glib, и вы можете использовать QEventLoop напрямую, вместо использования GLib apis.

+0

Спасибо большое. Я попробую и дам вам знать – samprat

+0

Я пробовал, и я обнаружил, что он входит в quitLoop при вызове из другого потока, но видео не останавливается – samprat

+0

@samprat Возвращает ли 'quitLoop'? –