Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.94/47: Рейтинг темы: голосов - 47, средняя оценка - 4.94
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348

Как остановить поток?

14.01.2020, 21:57. Показов 11079. Ответов 38
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Поиск простого числа, следующего за введённым. Разделил вычисления на 2 части, создал 2 потока, каждый из которых выполняет свою часть вычислений. При нахождении простого числа поток останавливается, но нужно остановить и второй, т.к. результат уже получен. Попробовал сделать это с помощью глобального флага, но не работает. Что я делаю не так?

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bool fl_stop = false;
 
potok::potok(quint64 x)
{
    i_beg = x;
}
 
 
 
void potok::run()
{
    quint64 max_i;
 
met_10:
 
    if(fl_stop) exec();
 
    max_i = sqrt(i_beg) + 1;
 
    for(quint64 i = 3; i <= max_i; i += 2)
    {
            if(!(i_beg % i))
            {
                i_beg += 4;
                goto met_10;
            }
    }
 
    emit get_rezult(i_beg);
    fl_stop = true;
    exec();
}
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.01.2020, 21:57
Ответы с готовыми решениями:

Как остановить поток?
Как остановить поток: Thread t = new Thread(NewThread); t.Start(); static void NewThread() { ...

Как остановить поток
Имеем код using System; using System.Threading; using System.Windows.Forms; namespace WindowsFormsApplication1 { ...

Как остановить поток?
Когда поставлена галочка в checkBox1, поток Monitor должен постоянно считывать текст из документа. Что он и делает, но поток не...

38
фрилансер
 Аватар для Алексей1153
6501 / 5737 / 1134
Регистрация: 11.10.2019
Сообщений: 15,372
17.01.2020, 14:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от alexu_007 Посмотреть сообщение
А вот поток с переопределённым run принудительно остановить (извне) так и не удалось пока.
так выше уже написали, как

Цитата Сообщение от Avazart Посмотреть сообщение
QThread::requestInterruption() и QThread::isInterruptionRequested()
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
17.01.2020, 14:43  [ТС]
В Qt 4.7 такого нет.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
17.01.2020, 14:51
Ну так это тот же флаг. Используйте std::atomic<bool> как флаг.
0
фрилансер
 Аватар для Алексей1153
6501 / 5737 / 1134
Регистрация: 11.10.2019
Сообщений: 15,372
17.01.2020, 14:54
alexu_007, тогда аналогия:

C++ (Qt)
1
std::atomic<bool> m_requestInterruption{false};//поле класса потока

где-то снаружи потока просим его остановиться:
C++ (Qt)
1
thread->m_requestInterruption=true;
в потоке в run проверка
C++ (Qt)
1
if(m_requestInterruption)return;
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 11:13  [ТС]
Протестил и то и другое. Потоки в обоих случаях останавливаются только если внутри цикла есть отправка сигнала. Если цикл ничего не отправляет "наружу" - он принудительно не останавливается, игнорит переменные.

У меня не было сигналов внутри потока - вот он и не останавливался.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.01.2020, 11:20
Цитата Сообщение от alexu_007 Посмотреть сообщение
Потоки в обоих случаях останавливаются только если внутри цикла есть отправка сигнала. Если цикл ничего не отправляет "наружу" - он принудительно не останавливается, игнорит переменные.
Быть такого не может. Измените код в моем примере вот так, вывод в консоль вместо сигналов. Все останавливается.
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include "Worker.h"
 
Worker::Worker(QObject *parent) : QObject(parent), m_isRunning(false)
{
 
}
 
bool Worker::isRunning() const
{
    return m_isRunning;
}
 
void Worker::slotRun()
{
    m_isRunning=true;
    //emit signalStart();
    qDebug()<<"thread started";
 
    while(m_isRunning){
        //here make all operations that you need
        QThread::msleep(1000);
        //emit signalStep();
        qDebug()<<"thread step";
    }
    //emit signalStop();
    qDebug()<<"thread stopped";
}
 
void Worker::slotStop()
{
    m_isRunning=false;
}
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 11:35  [ТС]
Цитата Сообщение от insite2012 Посмотреть сообщение
Быть такого не может. Измените код в моем примере вот так, вывод в консоль вместо сигналов. Все останавливается.
Не, ну возможно вывод в консоль работает аналогично отправке сигнала. Уберите весь вывод из потока - и он перестанет останавливаться.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.01.2020, 11:37
Цитата Сообщение от alexu_007 Посмотреть сообщение
Уберите весь вывод из потока - и он перестанет останавливаться.
С чего вы делаете такой вывод?
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 12:09  [ТС]
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void Worker::slotRun()
{
    quint64 summ = 0;
    m_isRunning = true;
 
    emit signalStart();
 
    while(m_isRunning)
    {
        //here make all operations that you need
        //QThread::msleep(1000);
 
        for(int j = 0; j < 60000000; j++)
        {
            summ++;
            if(!(j%17)) summ++;
        }
 
        emit signalStep(summ);
    }
 
    emit signalStop();
}
 
void Worker::slotStp()
{
    m_isRunning=false;
}
Вот ваш код, только у меня на 4.7 sleep не захотел работать, я заменил его реальными вычислениями - ну может так даже и лучше. Закомментируйте строчку с emit signalStep(summ); - кнопка stop перестаёт работать.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.01.2020, 12:14
Цитата Сообщение от alexu_007 Посмотреть сообщение
Закомментируйте строчку с emit signalStep(summ); - кнопка stop перестаёт работать.
Все работает.
Миниатюры
Как остановить поток?  
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 12:33  [ТС]
В режиме "отладка" работает, в режиме "релиз" - нет.
0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.01.2020, 12:58
Цитата Сообщение от alexu_007 Посмотреть сообщение
В режиме "отладка" работает, в режиме "релиз" - нет.
Сделайте флаг m_isRunning атомарным/
std::atomic<bool> m_isRunning;
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 13:54  [ТС]
У меня такое не компилируется. Это из-за 4.7?
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
20.01.2020, 14:28
Из-за старого компилятора или отсутствия флагов "С++11" для него.

Добавлено через 1 минуту
Можно по идее использовать еще https://doc.qt.io/qt-5/qatomicint.html
Про барьеры памяти тут послушать

0
Эксперт .NET
 Аватар для insite2012
5548 / 4311 / 1218
Регистрация: 12.10.2013
Сообщений: 12,371
Записей в блоге: 2
20.01.2020, 16:42
Avazart, спасибо, посмотрел, познавательная лекция.
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
20.01.2020, 17:26  [ТС]
С QAtomicInt заработало.
0
51 / 36 / 16
Регистрация: 24.01.2020
Сообщений: 94
Записей в блоге: 5
24.01.2020, 14:06
Кхм... Не флейма ради (да и тема уже старовата) спрошу: почему никто не посоветовал вручную внешние события обрабатывать в переопределенном методе run()?
QAbstractEventDispatcher:rocessEvents( ), без флага QEventLoop::WaitForMoreEvents.
Нет, я знаю, что "фу так делать" :-)
Но если по-серьезному делать - тогда надо вычислительный цикл в потоке представить в виде "микрозадания". Которое будет выполнять, допустим, 1000 шагов цикла - а потом самому себе сигнал посылать (на продолжение работы) через очередь сообщений потока и завершаться.
Тогда и внешний сигнал на завершение работы поток отработать может, как топикстартеру нужно.
Код получится сложноватым для понимания - это да.
0
737 / 704 / 110
Регистрация: 29.05.2015
Сообщений: 4,348
25.01.2020, 09:22  [ТС]
Цитата Сообщение от Dmitry Zhadan Посмотреть сообщение
Но если по-серьезному делать - тогда надо вычислительный цикл в потоке представить в виде "микрозадания". Которое будет выполнять, допустим, 1000 шагов цикла - а потом самому себе сигнал посылать (на продолжение работы) через очередь сообщений потока и завершаться.
Речь в моём случае идёт о быстродействии - для этого и два (и более) потоков. Допустим, идёт поиск в каком-то большом неотсортированном массиве данных. Делю массив на два и запускаю по потоку с каждой половинкой - какой-то поток найдёт первым - нужно остановить второй. Думаю, что идея посылать каждые 1000 циклов сигнал плохо скажется на быстродействии.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
25.01.2020, 12:34
Цитата Сообщение от Dmitry Zhadan Посмотреть сообщение
я знаю, что "фу так делать" :-)
Вы предлагаете советовать "фу" ? Это по Вашему в порядке вещей.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
25.01.2020, 12:34

Как остановить поток?
Как остановить поток вне метода в котором он был создан? Надеюсь, правильно сказал. Как я понял, нужны какие то модификаторы доступа?...

Как остановить поток?
Я видел подобную тему но применить это к своей программе я не сумел. У меня есть класс клиент и несколько методов, один из методов...

Как остановить поток
Здравствуйте, у меня в потоке выполняется код, а именно запрос idhttp1.get после запроса и обработки данных я в этом же потоке делаю...

Как остановить поток данных
Всем привет! Нужно записать поток данных введенных с клавиатуры в массив. Получилось так: #include &lt;stdio.h&gt; #define SIZE 255...

Как остановить поток из другой кнопки?
private void buttonpause_Click(object sender, EventArgs e) { mainLabel.Text = &quot;Работа алгоритма приостановлена....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
39
Ответ Создать тему
Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru