Russian Qt Forum
Март 29, 2024, 15:08
Добро пожаловать,
Гость
. Пожалуйста,
войдите
или
зарегистрируйтесь
.
Вам не пришло
письмо с кодом активации?
1 час
1 день
1 неделя
1 месяц
Навсегда
Войти
Начало
Форум
WIKI (Вики)
FAQ
Помощь
Поиск
Войти
Регистрация
Russian Qt Forum
>
Forum
>
Qt
>
Вопросы новичков
>
Пауза
Страниц: [
1
]
2
Вниз
« предыдущая тема
следующая тема »
Печать
Автор
Тема: Пауза (Прочитано 9150 раз)
Hero Sanya
Новичок
Offline
Сообщений: 34
Пауза
«
:
Май 20, 2020, 13:26 »
Как ставить функцию, выполняющуюся в потоке, на паузу, при нажатии кнопки?
Я сделал кнопочку, которая собирает данные с полей для ввода и отправляет их в функцию обработки, из неё, в функцию расчёта, в другом потоке(функция очень большая и долго считающая). Мне нужно, чтобы можно было прерывать выполнение этой функции в любой момент (нажимать на паузу). Я даже не представляю, что должно происходить в коде, при нажатии на кнопку "
пауза
".
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Пауза
«
Ответ #1 :
Май 20, 2020, 14:34 »
Ну если "без затей" то просто sleep в цикле, напр
Код
C++ (Qt)
void
CheckPause
(
void
)
while
(
pauseFlag
)
QThread
::
sleep
(
20
)
;
}
И повтыкать эту ф-цию в тело длинных расчетов. Ну а кнопочка устанавливает переменную pauseFlag. И, кстати, "прерывать" и "останавливать" не одно и то же
Записан
Авварон
Джедай : наставник для всех
Offline
Сообщений: 3257
Re: Пауза
«
Ответ #2 :
Май 20, 2020, 14:57 »
https://code.woboq.org/qt5/include/qt/QtCore/qfuture.h.html#_ZN7QFuture5pauseEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZNK20QFutureInterfaceBase8isPausedEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZN20QFutureInterfaceBase13waitForResumeEv
Записан
Hero Sanya
Новичок
Offline
Сообщений: 34
Re: Пауза
«
Ответ #3 :
Май 20, 2020, 16:10 »
Цитата: Igors от Май 20, 2020, 14:34
Ну если "без затей" то просто sleep в цикле, напр
Код
C++ (Qt)
void
CheckPause
(
void
)
while
(
pauseFlag
)
QThread
::
sleep
(
20
)
;
}
И по вставлять эту функцию в тело длинных расчетов. Кнопочка устанавливает переменную pauseFlag. И, кстати, "прерывать" и "останавливать" не одно и то же
Так, то есть, обернуть всю функцию с расчётами в кокон из while(pauseFlag)? На само деле я не знаю что такое pauseFlag. Я к тому, что, нужны ли там библиотеки? И я так подразумеваю, что в итоге пауза будет ставится не сразу по нажатию кнопки, а пока она сигнал не поймает?
Записан
Hero Sanya
Новичок
Offline
Сообщений: 34
Re: Пауза
«
Ответ #4 :
Май 20, 2020, 16:12 »
Цитата: Авварон от Май 20, 2020, 14:57
https://code.woboq.org/qt5/include/qt/QtCore/qfuture.h.html#_ZN7QFuture5pauseEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZNK20QFutureInterfaceBase8isPausedEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZN20QFutureInterfaceBase13waitForResumeEv
О май гад. Что это за гиганский h. файлы?
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Пауза
«
Ответ #5 :
Май 21, 2020, 10:47 »
Цитата: Hero Sanya от Май 20, 2020, 16:10
Так, то есть, обернуть всю функцию с расчётами в кокон из while(pauseFlag)?
Наоборот, вставить эту ф-цию в длинные расчеты, напр в тело цикла
Цитата: Hero Sanya от Май 20, 2020, 16:10
На само деле я не знаю что такое pauseFlag.
Обычная переменная (лучше член класса) которую Вам надо завести
Цитата: Hero Sanya от Май 20, 2020, 16:10
Я к тому, что, нужны ли там библиотеки?
Нет
Цитата: Hero Sanya от Май 20, 2020, 16:10
И я так подразумеваю, что в итоге пауза будет ставится не сразу по нажатию кнопки, а пока она сигнал не поймает?
Да, будет считать пока дело не дойдет до ф-ции
Цитата: Авварон от Май 20, 2020, 14:57
https://code.woboq.org/qt5/include/qt/QtCore/qfuture.h.html#_ZN7QFuture5pauseEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZNK20QFutureInterfaceBase8isPausedEv
https://code.woboq.org/qt5/qtbase/src/corelib/thread/qfutureinterface.cpp.html#_ZN20QFutureInterfaceBase13waitForResumeEv
Танки вперед
Я всегда считал футуру бездарной, ну может я не прав. Можно пример (пседокод, словами, как угодно) как ее задействовать в данном случае? Спасибо
Записан
Пантер
Administrator
Джедай : наставник для всех
Offline
Сообщений: 5876
Жаждущий знаний
Re: Пауза
«
Ответ #6 :
Май 21, 2020, 11:16 »
Я бы не стал использовать циклы со слипом, ибо это костыльное решение. На счет QFuture ничего сказать не могу, но я не уверен, что там так все просто, твой код должен поддерживать приостановку (если не прав, поправьте, самому лень читать доки).
Я поступил бы по-другому - реализовал расчеты так, чтобы можно было либо безболезненно остановить их, сохранив промежуточные результаты. Если это никак не получается, то хотя бы сделать все по-нормальному, используя QMutex, QSemaphore, QWaitCondition.
Записан
1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Пауза
«
Ответ #7 :
Май 21, 2020, 12:01 »
Цитата: Пантер от Май 21, 2020, 11:16
...ибо это костыльное решение.
Да. Зато "дешево, удобно, практично".
Цитата: Пантер от Май 21, 2020, 11:16
Я поступил бы по-другому - реализовал расчеты так, чтобы можно было либо безболезненно остановить их, сохранив промежуточные результаты. Если это никак не получается, ..
Такая возможность выпадает редко. Обычно расчет наструячит массу своих данных, объектов и.т.п. и сохранить/восстановить этот "контекст" оказывается неподъемным.
Цитата: Пантер от Май 21, 2020, 11:16
..то хотя бы сделать все по-нормальному, используя QMutex, QSemaphore, QWaitCondition.
Как только Вы попробуете привести пример "по-нормальному" - все окажется очень непросто
Записан
Авварон
Джедай : наставник для всех
Offline
Сообщений: 3257
Re: Пауза
«
Ответ #8 :
Май 21, 2020, 18:42 »
Цитата: Пантер от Май 21, 2020, 11:16
Я поступил бы по-другому - реализовал расчеты так, чтобы можно было либо безболезненно остановить их, сохранив промежуточные результаты. Если это никак не получается, то хотя бы сделать все по-нормальному, используя QMutex, QSemaphore, QWaitCondition.
И это ровно то что делает QFutureInterface=)
На самом деле надо попедалировать рассылку Qt на тему того чтобы переименовать его в QPromise и таки задокументировать (это уже всплывало ~месяц назад но как всегда заглохло)
Записан
Hero Sanya
Новичок
Offline
Сообщений: 34
Re: Пауза
«
Ответ #9 :
Май 21, 2020, 22:42 »
Так. В общем, я сделал три кнопки:Пауза, продолжить и старт. Старт запускает программу и она сидит в цикле(пока, не тру), если паузы так и не произошло, то просто выйдет из него поставив тру. По пути она будет считывать файл в котором будет лежать ключ(ну просто код), собственно этот код изменяется нажатием пауза. То есть пауза, просто берёт файл, переписывает его содержимое в единичку(можно сказать что это ключ для паузы). собственно, когда глобальная функция прочтёт из файла единицу, она войдёт в замкнутый цикл.На всякий случай я там оставил таймер. там тоже происходит чтение файла и если была нажата кнопка продолжить, файл пере пишется ну, на любую другую цифру(например 2). То есть файлом, можно игнорировать такую вещь, как потоки и передавать послания в любые другие потоки или основной. Можете назвать это костылём, но это работает идеально, так ещё и оставляет возможность для модификаций, например для сериализации кода(что пригодится для сохранения и загрузки).
В итоге: Пауза и продолжить, просто переписывают по нажатию кнопки текст в файле, а циклы являются скажем так, контрольными точками или чекпоинтами.
Записан
Hero Sanya
Новичок
Offline
Сообщений: 34
Re: Пауза
«
Ответ #10 :
Май 21, 2020, 23:01 »
Если кому нужно, я приложу своё решение проблемы с паузой. Однако, тут я всё ещё не знаю, как реализовать неактивные кнопки(НО я думаю, это тема другой..эмм. темы). Так же, я считаю. что тут единственная дыра, это когда пользователь нажмёт на кнопку во время чтения из файла. С другой стороны, для выхода из паузы, можно придумать один единственный код: какие нибудь 8888, да он пропустит одну итерацию в цикле, но в итоге всё ровно продолжит программу.
.h
Код:
#ifndef THREE_H
#define THREE_H
void start(bool stoper);
#endif // THREE_H
.Cpp
Код:
#include "mainwindow.h"
#include <math.h>
#include <iostream>
using namespace std;
#include <thread> //две библиотеки,
#include <chrono> //для потоков
#include "three.h"
#include <stdlib.h>
void one(bool stoper){
int i=0;
char str[10];
int n=0;
FILE* fan;
while(stoper==false){
cout<<"i="<<i<<endl; i++;
this_thread::sleep_for(chrono::milliseconds(1500));
fan=fopen("test.txt","r");
while(!feof (fan)) {
if (fgets(str, 10, fan))
n = atoi(str);
cout<<"s="<<str<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
cout<<"n="<<n<<endl;
this_thread::sleep_for(chrono::milliseconds(1000));
}
this_thread::sleep_for(chrono::milliseconds(3000));
if(n==1){
while(n==1){
cout<< "pause" << endl;
this_thread::sleep_for(chrono::milliseconds(1000));
rewind(fan);
while(!feof (fan)) {
cout<< "@";
if (fgets(str, 10, fan))
n = atoi(str);
cout<<"n in pause="<< n << "pause" << endl;
}
}
cout<< "continue" << endl;
this_thread::sleep_for(chrono::milliseconds(200));
}
//stoper=true;
}
fclose(fan);
}
void start(bool stoper){
thread th(one,stoper);
th.detach();
}
MainWindow::MainWindow(QWidget *parent):
Код:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
FILE* fn;
fn=fopen("test.txt", "w");
fprintf(fn,"111");
fclose(fn);
}
Кнопки(Да, я там использовал глобальную переменную, которую и хотел изменять, её по сути можно удалить):
Код:
bool stoper=false;
void MainWindow::on_pushButton_clicked()//старт
{
if(stoper==false)
start(stoper);
}
void MainWindow::on_pushButton_2_clicked()//пауза
{ FILE* f;
f=fopen("test.txt","w");
if(f == NULL)
{
printf("не могу открыть файл '%s'", "test.txt");
} else
fprintf(f,"1");
fclose(f);
}
void MainWindow::on_pushButton_3_clicked()//продолжить
{
FILE* f;
f=fopen("test.txt","w");
if(f == NULL)
{
printf("не могу открыть файл '%s'", "test.txt");
} else
fprintf(f,"32");
fclose(f);
}
Записан
Пантер
Administrator
Джедай : наставник для всех
Offline
Сообщений: 5876
Жаждущий знаний
Re: Пауза
«
Ответ #11 :
Май 21, 2020, 23:02 »
>То есть файлом, можно игнорировать такую вещь, как потоки и передавать послания в любые другие потоки или основной
Угу. А про кеширование файловой системы ты не слышал? Обрабатываешь ситуацию, если файл пустой? А если двое сразу запишут в него что-нибудь?
Записан
1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Hero Sanya
Новичок
Offline
Сообщений: 34
Re: Пауза
«
Ответ #12 :
Май 21, 2020, 23:45 »
Цитата: Пантер от Май 21, 2020, 23:02
>То есть файлом, можно игнорировать такую вещь, как потоки и передавать послания в любые другие потоки или основной
Угу. А про кеширование файловой системы ты не слышал? Обрабатываешь ситуацию, если файл пустой? А если двое сразу запишут в него что-нибудь?
Это просто пример паузы. Переписывать файл могут только пауза и продолжить(просто в этом примере они активны одновременно, что ошибка).
На счёт игнорирования, я имел ввиду, что можно организовать общение потоков через файловую систему.
Да, тут нету обработок на случай если файл пустой, просто я в маинвиндовс, сразу создаю файл заполненным. Другое дело. если кто то целенаправленно захочет удалить или переписать файл(ну а это ровно тоже самое, если переписать любой файл программы).
Записан
Igors
Джедай : наставник для всех
Offline
Сообщений: 11445
Re: Пауза
«
Ответ #13 :
Май 22, 2020, 10:21 »
Цитата: Hero Sanya от Май 21, 2020, 22:42
То есть файлом, можно игнорировать такую вещь, как потоки и передавать послания в любые другие потоки или основной. Можете назвать это костылём, но это работает идеально, так ещё и оставляет возможность для модификаций, например для сериализации кода(что пригодится для сохранения и загрузки).
Обычно подобные городушки лепятся для процессов (впрочем и там это плохо), но для потоков, где память общая, зачем же читать файл в цикле?
Цитировать
— Но зачем же брить яйца наголо, поручик?
— Дикари-с.
Цитата: Авварон от Май 21, 2020, 18:42
И это ровно то что делает QFutureInterface=)
Не слышал о таком, но рискну утверждать что для данной задачи (т.е. (при)остановить один но длинный расчет) он ничем не поможет. Т.к. задача по своей природе "интрузивна", т.е. ф-ция останова должна быть внедрена в код расчетов, сделать это чисто "извне" невозможно.
Вообще затрудняюсь вспомнить случай когда мне нужно было чего-то там "подсматривать" при параллельном выполнении. Индикатор - да, а вот тот же (при)останов - крайне редко. Обычно нужно выжать скорость, поэтому все эти футуры, промисы и.т.п. мне без надобности.
Записан
Пантер
Administrator
Джедай : наставник для всех
Offline
Сообщений: 5876
Жаждущий знаний
Re: Пауза
«
Ответ #14 :
Май 22, 2020, 10:40 »
Соглашусь с Igors, для возможности останова должен быть модифицирован код. А любое добавление проверок или индикации в код расчета замедлит его в разы. Если возможно, можно разбить расчет на несколько этапов и делать проверки между этими этапами. Соответственно, в данном случае можно будет и сохранить текущее состояние расчетов.
Записан
1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
Страниц: [
1
]
2
Вверх
Печать
« предыдущая тема
следующая тема »
Перейти в:
Пожалуйста, выберите назначение:
-----------------------------
Qt
-----------------------------
=> Вопросы новичков
=> Уроки и статьи
=> Установка, сборка, отладка, тестирование
=> Общие вопросы
=> Пользовательский интерфейс (GUI)
=> Qt Quick
=> Model-View (MV)
=> Базы данных
=> Работа с сетью
=> Многопоточное программирование, процессы
=> Мультимедиа
=> 2D и 3D графика
=> OpenGL
=> Печать
=> Интернационализация, локализация
=> QSS
=> XML
=> Qt Script, QtWebKit
=> ActiveX
=> Qt Embedded
=> Дополнительные компоненты
=> Кладовая готовых решений
=> Вклад сообщества в Qt
=> Qt-инструментарий
-----------------------------
Программирование
-----------------------------
=> Общий
=> С/C++
=> Python
=> Алгоритмы
=> Базы данных
=> Разработка игр
-----------------------------
Компиляторы и платформы
-----------------------------
=> Linux
=> Windows
=> Mac OS X
=> Компиляторы
===> Visual C++
-----------------------------
Разное
-----------------------------
=> Новости
===> Новости Qt сообщества
===> Новости IT сферы
=> Говорилка
=> Юмор
=> Объявления
Загружается...