Как “выключить” поток?

194
23 августа 2018, 10:00

По моей задумке, я создаю вектор потоков, запускаю его на нажатие CheckBox-а, на отжатие CheckBox-а происходит завершение потока.

На деле при нажатии CheckBox-а он запускает отдельный поток, НО при отжатии CheckBox-а не отрабатывается завершение потока.

Что я делаю не так ??

Вот кусок кода где происходит данное действо:

void MainWindow::start_sending(bool Value)
{
    NewsThread *two_cl = new NewsThread(); // инициализируем второй класс
    if (test_checkbox_old == 0)
    {
        test_checkbox_old = test_checkbox.length();
        qDebug() << "test_checkbox_old" <<test_checkbox_old ;
        seting_clear(test_checkbox_old);
    }
    if (test_checkbox_old != test_checkbox.length())
    {
        qDebug() << "!test_checkbox_old" <<test_checkbox_old ;
        seting_clear(test_checkbox_old, test_checkbox.length());
        test_checkbox_old = test_checkbox.length();
    }
    for(int i =0; i< test_checkbox.length();i++)
    {
        if (Value == true)
        {
            if(test_checkbox[i]->isChecked() == true)
            {
                if(togled_checked_sensor[i] == 0)
                {
                    qDebug() << " светлая сторона  " <<  i;
                    togled_checked_sensor[i] = 1;
                    connect(test_checkbox[i], SIGNAL(stateChanged(int, QString, int)), two_cl , SLOT(run_NEW(int, QString, int)));// от кого, "реакция", кому, "выполнение"
                    two_cl->moveToThread(vector_thread[i]);
                    vector_thread[i]->start();
                }
            }
        }
        // обратный метод очистки
        if(Value == false)
        {
            if(test_checkbox[i]->isChecked() == false)
            {
                if(togled_checked_sensor[i] == 1)
                {
                    togled_checked_sensor[i] = 0;
                    qDebug() << " темная сторона  " <<  i;
//                    vector_thread[i]->quit(); // чёт не работает
                    vector_thread[i]->exit(); // чет тоже не работает
                }
            }
        }
    }
void MainWindow::seting_clear(int i)
{
    for (int f =0 ; f<i; f++)
    {
        thread = new QThread(); // инициализ класс потока из за того что
        vector_thread.append(thread);
        qDebug() << " f :" << f;
    }
}
void MainWindow::seting_clear(int i, int f)
{
    f = f-i;
    for(int a =0; a<f;a++)
    {
        thread = new QThread();
        vector_thread.append(thread);
        qDebug() << " a :" << a;
    }
}

а вот где "работает" циклом поток

     void NewsThread::run_NEW(int i, QString str, int f)
    {
        // -- вот тут механизм гетеров сетеров
        Foo *FO = new Foo();
        FO->setData(155);
        for(;;){ // вечный цикл
        if( QThread::currentThread()->isInterruptionRequested()  )
        {
            for (int i=0; i<500; i++)
            {
                qDebug()<< "Число :" << i <<"номер \"потока\" :" << str ;
                qDebug()<< "Тут переменная котрая задаётся в маинвиндовс класе переходит в майчекбокс и возвращаеться сюда: "  ;
                qDebug()<< "QThread::currentThreadId() : "<< QThread::currentThreadId();
                 qDebug()<< "Число переданное из майчекбокс :" << f <<" FO.getData: " << FO->getData() ;
                usleep(100);
             }
          }
      }
    }
Answer 1

Пользователь @vegorov дал ответ.

Надо было отказаться от вечного цикла, и воспользоваться функцией requestInterruption()

Вот код который изменился (всё остальное осталось прежним)

    // обратный метод очистки
    if(Value == false)
    {
        if(test_checkbox[i]->isChecked() == false)
        {
            if(togled_checked_sensor[i] == 1)
            {
                togled_checked_sensor[i] = 0;
                qDebug() << " темная сторона  " <<  i;
                //  vector_thread[i]->quit();
                vector_thread[i]->requestInterruption(); // !!! НОВЫЙ ДОБАВЛЕННЫЙ КОД 
                vector_thread[i]->exit();
            }
        }
    }

А вот функция вызова

void NewsThread::run_NEW(int i, QString str, int f)
{
    // -- вот тут механизм гетеров сетеров
    Foo *FO = new Foo();
    FO->setData(155);
    // Отказался от вечного цикла  
    for(int i=0; i<500; i++) 
    {
        qDebug()<< "Число :" << i <<"номер \"потока\" :" << str ;
        qDebug()<< "QThread::currentThreadId() : "<< QThread::currentThreadId();
         qDebug()<< "Число переданное из майчекбокс :" << f <<" FO.getData: " << FO->getData() ;
        usleep(100);
        if (i == 499)
        {
            if( QThread::currentThread()->isInterruptionRequested() == true ) // !!! НОВЫЙ ДОБАВЛЕННЫЙ КОД
            {
                qDebug() << " tyt";
                return;
            }
                else
                i = 0;
        }
    }
}
READ ALSO
ГОСТ 28147-89 (Режим простой замены). (C++) - CUDA

ГОСТ 28147-89 (Режим простой замены). (C++) - CUDA

В программе реализовывается алгоритм шифрования ГОСТ 28147-89 в режиме простой заменыИзначально хотел сделать шифрование и дешифрование на CPU и на GPU

237
Как прилинковать нестандартную версию boost через cmake (не хедеронли часть).

Как прилинковать нестандартную версию boost через cmake (не хедеронли часть).

Есть проект под arm который компилируется и собирается на х86ой машине (кросскомпиляция)Есть версия библиотеки boost собранная под arm

182
Как сделать метод универсальным?

Как сделать метод универсальным?

Пишу метод упрощающий чтение кода и никак не могу сделать его так, что бы он был универсальный

184