С Новым годом! Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.78/27: Рейтинг темы: голосов - 27, средняя оценка - 4.78
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121

Принудительный выход из цикла - отдельный поток или другое решение?

13.10.2011, 19:41. Показов 5156. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Visual Studio 2008 SP1, диалоговый проект MFC.
В таблицу загружаются данные (цикл примерно из 9000 проходов). Операция занимает не 1 минуту. Нужно каким-то способом останавливать процесс загрузки (например, по нажатию клавиши Esc). Но пока идет заполнение таблицы, окно программы не принимает никакие сообщения. Как лучше это реализовать? Пробовал создавать отдельный поток (до этого с многопоточностью не работал, поэтому плохо в них разбираюсь).
C++
1
2
3
4
5
6
7
8
9
10
11
12
UINT myThread(LPVOID Param)
{
    CTablicaDlg::FillGrid(); // Строка 1: Функция FillGrid() - public метод класса CTablicaDlg
    return 0;
}
 
void CTablicaDlg::RefreshGrid()
{
    //...
    AfxBeginThread(myThread, this);
    //...
}
В строке 1 выдавало 2 ошибки:
C2248: 'CTablicaDlg::FillGrid' : cannot access protected member declared in class 'CTablicaDlg'.
C2352: 'CTablicaDlg::FillGrid' : illegal call of non-static member function.
Собирался по нажатию Esc присвоить переменной цикла значение 9000, что остановило бы цикл.
Гугление ни к чему не привело. Точнее нашел кое-что:
C++
1
2
3
4
5
6
UINT myThread(LPVOID Param)
{
    CTablicaDlg *pDlg = reinterpret_cast<CTablicaDlg>(Param);
    pDlg->FillGrid();
    return 0;
}
но мне не помогло. Тоже ошибки - С2248 из примера выше и C2440: 'reinterpret_cast' : cannot convert from 'LPVOID' to 'CTablicaDlg'.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.10.2011, 19:41
Ответы с готовыми решениями:

Принудительный выход из цикла
Задача: пользователь вводит текст, если в тексте встречается запятая, вывести какая самая первая запятая по счету. вот мой код: ...

Принудительный выход из цикла for
Есть несколько вложеных циклов фор, как сделать принудительный выход из внутренего?

Принудительный выход из цикла
Вообщем надо при определенном условии завершать вложенный цикл, такой код будет работать??? for(.....) { for(.....) { if...

27
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
13.10.2011, 23:03
Цитата Сообщение от UFO665 Посмотреть сообщение
CTablicaDlg *pDlg = reinterpret_cast<CTablicaDlg>(Param);
CTablicaDlg *pDlg = (CTablicaDlg *)Param
Цитата Сообщение от UFO665 Посмотреть сообщение
C2248: 'CTablicaDlg::FillGrid' : cannot access protected member declared in class 'CTablicaDlg'.
А где описание CTablicaDlg
здесь он говорит что метод только для наследников (protected member) и снаружи класса не достучатся
Цитата Сообщение от UFO665 Посмотреть сообщение
C2352: 'CTablicaDlg::FillGrid' : illegal call of non-static member function.
а здесь просит чтобы он был статическим
Цитата Сообщение от UFO665 Посмотреть сообщение
Но пока идет заполнение таблицы, окно программы не принимает никакие сообщения.
попробуй в цикле поставить sleep(100)
дай отдохнуть процессору

Добавлено через 2 минуты
можно попробовать переопределить IsIdle и в ней заполнять структуру
она будет вызыватся когда очередь сообщений у окна пуста
0
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121
13.10.2011, 23:17  [ТС]
ValeryS, если sleep(100) поставить, то время выполнения увеличится на 900 секунд) попробую CTablicaDlg *pDlg = (CTablicaDlg *)Param и еще поковыряться. Спасибо за ответ
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
13.10.2011, 23:21
поставь sleep(10) sleep(5)
главное дать процессору отвлечься от твоего цикла
0
Mobile Developer
 Аватар для lifestyle
238 / 234 / 18
Регистрация: 10.05.2009
Сообщений: 917
13.10.2011, 23:48
хм, а не проще ли использовать winAPI поместив в цикл функцию которая проверяет и достает из стэка сообщений если таковое имеется и дальнейшая обработка данного сообщения сообщение может быть любое, пусть то будет клавиша ESC или еще что-то , так же можно ограничить обработку сообщения если только будет нажата нужная кнопка. Функция- PeekMessage()

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
поставь sleep(10) sleep(5)
главное дать процессору отвлечься от твоего цикла
Каким образом это даст возможность обработать нажатие клавиши если будет задержка?)))))
даже если дать дополнительный поток, тогда эта задержка также никчему)
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
13.10.2011, 23:58
Цитата Сообщение от lifestyle Посмотреть сообщение
м, а не проще ли использовать winAPI поместив в цикл функцию которая проверяет и достает из стэка
можно
Цитата Сообщение от lifestyle Посмотреть сообщение
даже если дать дополнительный поток, тогда эта задержка также никчему)
очень даже к чему
даст переключится потокам
0
Mobile Developer
 Аватар для lifestyle
238 / 234 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.10.2011, 00:00
Цитата Сообщение от ValeryS Посмотреть сообщение
очень даже к чему
даст переключится потокам
т.е. если у меня в приложении прусутствует более одного потока, то при обработке одного потока без задержки второй поток не будет выполнятся?)))
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
14.10.2011, 00:04
Цитата Сообщение от lifestyle Посмотреть сообщение
то при обработке одного потока без задержки второй поток не будет выполнятся?
будет
я говорю о ресурсоемких потоках которые могут захватить процессор (зависит и от приоритета)
и другой поток будет вызываться неравномерно с задержками
а слип это исправляет(сталкивался не один раз)
0
Mobile Developer
 Аватар для lifestyle
238 / 234 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.10.2011, 00:15
скачки между потоками происходят не равномерно по определению))))
в любом случае задержка не для данных целий необходима и создавалась.ИМХО это не грамотное решение на худой конец вставить в конец или начало цикла какой нибудь if который бы проверял нажали ли кнопкуу или нет, но ни как не создавать для данной задачи два потока и вставлять задержки в ресурсоемкий цикл.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
14.10.2011, 00:37
Цитата Сообщение от lifestyle Посмотреть сообщение
но ни как не создавать для данной задачи два потока
а не для данной
например чтение с ком порта???
Цитата Сообщение от lifestyle Посмотреть сообщение
вставлять задержки в ресурсоемкий цикл.
ты ведь не знаешь (и я не знаю)что там за цикл и почему он не отдает управление

Добавлено через 3 минуты
Цитата Сообщение от lifestyle Посмотреть сообщение
икла какой нибудь if который бы проверял нажали ли кнопкуу
а если не кнопку ?
если поток захватит процессор тут и перерисовка тормознет и другие приложения подвиснут
(никогда не сталкивался?)
0
Mobile Developer
 Аватар для lifestyle
238 / 234 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.10.2011, 01:01
Цитата Сообщение от ValeryS Посмотреть сообщение
а если не кнопку ?
если поток захватит процессор тут и перерисовка тормознет и другие приложения подвиснут
(никогда не сталкивался?)
поэтому и прделожил изьятие сообщения из стека сообщений если оно там имеется))
а задержкой ты увеличиваешь и так большое время обработки...

а для чтения с ком порта-то зачем два потока?)
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
14.10.2011, 01:06
Цитата Сообщение от lifestyle Посмотреть сообщение
а для чтения с ком порта-то зачем два потока?)
затем что реад ждет что либо с порта и если ничего не приходит то не возвращает управления
программа повисла
а если в одном потоке чтение
а в другом управление то все путем
это не только с комом это и с интернетом может быть
0
14.10.2011, 02:18

Не по теме:

Цитата Сообщение от ValeryS Посмотреть сообщение
затем что реад ждет что либо с порта и если ничего не приходит то не возвращает управления
программа повисла
а если в одном потоке чтение
а в другом управление то все путем
это не только с комом это и с интернетом может быть
хм, а таймауты зачем тогда?)))
http://www.robbayer.com/files/serial-win.pdf
и вообще в оффтоп уже ушли))

1
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
14.10.2011, 12:47
Не пойму о чем спор. Второй поток вполне разумный и пригодный способ решения данной проблемы. И, наверное, самый простой. И не нужно в нем никаких sleep.
0
14.10.2011, 14:50

Не по теме:

Цитата Сообщение от bigredcat Посмотреть сообщение
Не пойму о чем спор. Второй поток вполне разумный и пригодный способ решения данной проблемы. И, наверное, самый простой. И не нужно в нем никаких sleep.
об этом то и речь, что sleep не нужен.а поток не нужен так как есть таймауты)))

0
14.10.2011, 16:25

Не по теме:

lifestyle, и что, это работает и с дисковыми файлами? А если нет чтения/записи, например, интенсивные вычисления?

0
2 / 2 / 1
Регистрация: 24.03.2010
Сообщений: 121
14.10.2011, 18:53  [ТС]
Переправил на CTablicaDlg *pDlg = (CTablicaDlg *)Param, но скомпилилась только после написания слова "public" перед самой функцией в классе (хотя она и так была public, странно). Теперь при выполнении FillGrid() вылезает debug assertion failed. Упрощенный код этой функции (с пометкой места ошибки) ниже:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void CTablicaDlg::FillGrid()
{
    for(int i = 0; i < 9000; i++)
    {
        // Заполнение 1-го столбца i-й строки
        // Заполнение 2-го столбца i-й строки
        // ...
        // Заполнение 16-го столбца i-й строки
    }
 
    Filtration(); // ОШИБКА ЗДЕСЬ (а именно в 1-й строке Filtration() - UpdateData(TRUE))
    // Filtration() - метод класса CTablica, фильтрует строки
    //...
}
А вообще внутри FillGrid() есть еще обращения к методам класса CTablicaDlg и методам классов, объявленных в CTablicaDlg. Подозреваю, что и при их выполнении будет не все гладко. Вынести все эти обращения из FillGrid() невозможно.
Еще один момент. FillGrid() вызывается не 1 раз, т.е. 9000 проходов делаются не сразу. Получается, что каждый раз при обращении к FillGrid() будет создаваться новый поток.
Цитата Сообщение от lifestyle Посмотреть сообщение
хм, а не проще ли использовать winAPI поместив в цикл функцию которая проверяет и достает из стэка сообщений если таковое имеется и дальнейшая обработка данного сообщения сообщение может быть любое, пусть то будет клавиша ESC или еще что-то , так же можно ограничить обработку сообщения если только будет нажата нужная кнопка. Функция- PeekMessage()
Можно поподробнее о том, как это осуществить? Желательно с кодом.
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
14.10.2011, 19:04
назовите мне разницу между слипом и таймаутом (не на уровне академической науки, а на уровне прикладника)задача одна и та же отобрать у процесса время
слип это не типа цикл задержка на скоко-то секунд
слип он и есть слип(уснуть) а не задержка (делай)
0
Mobile Developer
 Аватар для lifestyle
238 / 234 / 18
Регистрация: 10.05.2009
Сообщений: 917
14.10.2011, 19:23
Простенький пример реализации...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void OnPlay(HWND hWnd) 
{
 MSG message;
 while (IfReadData.eof()) 
 {
    fReadData.read(buf, 512);
    // Предотвращение зависания приложения
    if (PeekMessage(&message, hWnd, 0, 0, PM_REM0VE))  // тут происходит проверка очереди сообщений приложения.
       //если там есть сообщения, т.е. предпринимались некие действия во время вполнения программы то мы достаем последнее сообщение 
       // и обрабатываем его , а так же удаляем из стека не дожидаяс окончания цикла или работы приложения.
    {
       TranslateMessage(&message);
       DispatchMessage(&message);
    }
    DoSomething() ; // какая-нибудь обработка
 }
}
Цитата Сообщение от ValeryS Посмотреть сообщение
назовите мне разницу между слипом и таймаутом (не на уровне академической науки, а на уровне прикладника)задача одна и та же отобрать у процесса время
слип это не типа цикл задержка на скоко-то секунд
слип он и есть слип(уснуть) а не задержка (делай)
)))а разница что при вызове слипа ничего не выполняется т.е. засыпает поток.
а таймаут ,в случае с ком портом расмотренный выше пример, на протяжении которого поток пытается считать данные и если таймаут исчерпан чтение заканчивается и продолжается дальше т.е. ReadFile возвращает управление потоку даже если ничего не было прочитано с порта по истечении таймаута...
1
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
14.10.2011, 19:38
Цитата Сообщение от UFO665 Посмотреть сообщение
Переправил на CTablicaDlg *pDlg = (CTablicaDlg *)Param, но скомпилилась только после написания слова "public" перед самой функцией в классе (хотя она и так была public, странно).
ты весь код выложи
а не понятно о чем речь!
навскидку обратными функциями (цал бэк) могут быть только статические или глобальные функции
оно и понятно
объектов может быть до проха а а функция должна быть в памяти одна (иначе куда системе передавать управление)
посему статическая функция не имеет доступа к элементам класса
х=0
к какому х мы обращаемся
нужно писать так
this->x=0
обрашение к переменной х текущего элемента

извините если объяснил сумбурно
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
14.10.2011, 19:38
Помогаю со студенческими работами здесь

Принудительный выход из цикла foreach
Доброго времени суток! Прочитал в интернете, что есть оператор break, но он почему-то выход не осуществляет. Ситуация следующая. Есть...

Принудительный выход из программы
Привет! У меня такая проблемка: есть программа в которой реализовано главное меню(имеется цикл while а внутри цикла реализован switch) ...

Принудительный выход из метода
Задача:Ведите логин и пароль ,если пароль верный пустить в систему,нет пускай вводит еще раз . Попытки ввода ограничить 3. У меня...

Принудительный выход из прерывания на СИ
Доброго времени всем форумчанам. Столкнулся с проблемой - нужно выйти из прерывания раньше времени, т.е. я захожу в INT0, проверяю условие,...

Принудительный выход из программы не работает
Есть такой метод для выхода из программы. private void Exit() { if...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Модель микоризы: классовый агентный подход
anaschu 02.01.2026
Раньше это было два гриба и бактерия. Теперь три гриба, растение. И на уровне агентов добавится между грибами или бактериями взаимодействий. До того я пробовал подход через многомерные массивы,. . .
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути
Programma_Boinc 01.01.2026
Учёным и волонтёрам проекта «Einstein@home» удалось обнаружить четыре гамма-лучевых пульсара в джете Млечного Пути Сочетание глобально распределённой вычислительной мощности и инновационных. . .
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru