Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/13: Рейтинг темы: голосов - 13, средняя оценка - 4.77
4 / 4 / 2
Регистрация: 24.05.2013
Сообщений: 300

Область видимости общей переменной для потоков + закрытие потоков

07.06.2017, 00:22. Показов 2913. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть два вопроса про потоки.
Первый. Как можно сделать общую переменную для основного потока и моих ?
C++
1
2
3
4
5
6
7
struct ThreadInfo1 {
    int func_counter; // считаем кол-во вызовов поточной функции
    int break_flag; // выйдем из потока по флагу
};
...
ThreadInfo1 myThreadInfo = { 0,0 }; // есть общая структура. ОК.
hThread = CreateThread(nullptr, 0, &ThreadProc1, &myThreadInfo, 0, nullptr); // передадим ее
C++
1
2
3
4
5
DWORD WINAPI ThreadProc1(LPVOID lpParameter) {
    ((ThreadInfo1*)lpParameter)->func_counter++;
    while (1) if (((ThreadInfo1*)lpParameter)->break_flag == 1) break;
    return 0;
}
Поток работает и постоянно проверяет мой флаг выхода. Если где-то в основном я его установлю, то поток выйдет.
C++
1
myThreadInfo.break_flag = 1;
Но такой подход работает только в режиме Debug. В Release в рамках оптимизации такой подход не канает. Как использовать ключевое слово volatile ?
C++
1
2
volatile ThreadInfo1 myThreadInfo = { 0,0 };
hThread = CreateThread(nullptr, 0, &ThreadProc1, (LPVOID) &myThreadInfo, 0, nullptr); // в релизе все равно не работает.
Второй вопрос. Как можно закрыть все потоки, созданные мною ? Ну или вернее, закрыть все потоки, кроме основного? Пытался ходить по все потокам и рубить все, кроме текущего, но вылетает исключение из ntdll.dll. Что с этим делать ? Тактики, стратегии, что угодно...
C++
1
2
3
4
5
6
7
8
9
10
do
    {
        if (te32.th32OwnerProcessID == current_PID) {
            hThread = OpenThread(THREAD_TERMINATE, FALSE, te32.th32ThreadID);
            if (te32.th32ThreadID != GetCurrentThreadId()) {
                    TerminateThread(hThread, 0);
            }
            CloseHandle(hThread);
        }
    } while (Thread32Next(hThreadSnap, &te32));
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
07.06.2017, 00:22
Ответы с готовыми решениями:

Синхронизация двух потоков с общей переменной
добрый вечер, стоит следующая задача: Напишите программу, в которой первый поток построчно считывает содержимое некоторого текстового...

Общение пхп потоков, есть ли область видимая для всех пхп потоков?
Добрый день форумчане. Суть вопроса такова - сайт работает с апи вк, как известно у вк есть ограничение: запросы к апи должны идти не...

Задать область видимости переменной для всех форм
Как заставить проделывать работу без отображения формы. Например есть button1 на form1 нажимаем на кнопку, переходим к другому...

5
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
07.06.2017, 01:03
Цитата Сообщение от Evgen8 Посмотреть сообщение
Как использовать ключевое слово volatile ?
Сделай volatile соответствующее поле структуры, а не саму структуру.
Либо используй atomic из Boost или std.

Цитата Сообщение от Evgen8 Посмотреть сообщение
Как можно закрыть все потоки, созданные мною ?
Закрыть? Хм, ну CloseHandle ведь никто не отменял...
0
4 / 4 / 2
Регистрация: 24.05.2013
Сообщений: 300
07.06.2017, 01:08  [ТС]
Цитата Сообщение от Убежденный Посмотреть сообщение
Сделай volatile соответствующее поле структуры
минут через 10 после публикации пришел к этому )
Цитата Сообщение от Убежденный Посмотреть сообщение
Закрыть? Хм, ну CloseHandle ведь никто не отменял...
Закрытие дескриптора не завершает сам поток. Или что-то другое имелось ввиду ?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
07.06.2017, 01:17
А, ты об этом... Ну тогда надо в поток отправить какой-то сигнал, чтобы он
вернул управление системе. Это правильный путь. TerminateThread ведет к
"провалу всей операции", ибо поток прибивается в совершенно неопределенный
момент, где, например, могут удерживаться блокировки и т.д.
0
4 / 4 / 2
Регистрация: 24.05.2013
Сообщений: 300
07.06.2017, 01:36  [ТС]
Убежденный, что за сигнал ? Как ?
Для моего потока это зайдет, там где на цикле проверяется флаг выхода. Но в любом другом случае же будет сложнее, надо будет периодически проверять флаг выхода.
С TerminateThread проблема только в том, что он не закрывает основной поток, но закрывает потоки, от которых зависит основной. (я их не создавал) Может быть можно проверить как-то можно ли закрыть поток (наличие флага THREAD_TERMINATE) . Либо же хранить список ХАНДЛОВ моих потоков, в закрытии которых (без исключений) я уверен.

Добавлено через 7 минут
+ если поток переведен в режим SuspendThread(), то выйти из него его же средствами не выйдет.

Добавлено через 3 минуты
+ сейчас такая ситуация, что я имею некоторое число потоков, которые я создал. Я это число знаю. Все потоки в режиме Suspended. К моим потокам прибавляется основной и еще несколько потоков, которые я не добавлял, но они есть. Как правило от 1 до 4. Как в данной ситации правильно закрыть все мои потоки ? Просто гулять по всему списку потоков и пробуждать их все, чтобы они могли сами по флагу выйти - я не могу. Как отличить мой от не моих...?
0
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
07.06.2017, 09:40
Лучший ответ Сообщение было отмечено Evgen8 как решение

Решение

Цитата Сообщение от Evgen8 Посмотреть сообщение
Убежденный, что за сигнал ? Как ?
Да хоть event, хоть глобальная переменная...
Поток, получив такой сигнал, должен выйти из функции. Тогда он завершится.
Это ЕДИНСТВЕННЫЙ корректный способ завершения потока, других не существует
(и не нужно даже пытаться лепить какие-то "костыли" - оно не будет корректно работать).

Цитата Сообщение от Evgen8 Посмотреть сообщение
+ если поток переведен в режим SuspendThread(), то выйти из него его же средствами не выйдет.
Ну разумеется. А зачем тогда делать SuspendThread?
Это вообще функция для отладки и прочих специальных вещей, в 99% нормального софта таких
функций не должно быть.

Цитата Сообщение от Evgen8 Посмотреть сообщение
сейчас такая ситуация, что я имею некоторое число потоков, которые я создал. Я это число знаю. Все потоки в режиме Suspended. К моим потокам прибавляется основной и еще несколько потоков, которые я не добавлял, но они есть. Как правило от 1 до 4. Как в данной ситации правильно закрыть все мои потоки ?
См. выше. Нужно дать потокам какой-то сигнал на завершение. А затем дождаться,
пока все соответствующие хэндлы не перейдут в сигнальное состоение. Другого пути нет.

Цитата Сообщение от Evgen8 Посмотреть сообщение
Просто гулять по всему списку потоков и пробуждать их все, чтобы они могли сами по флагу выйти - я не могу.
Значит, меняй архитектуру программы. Потому что иначе ничего не получится.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.06.2017, 09:40
Помогаю со студенческими работами здесь

Открытие-закрытие потоков
Че то запутался , как из такой ситуации выйти. private void button6_Click(object sender, EventArgs e) { ...

Принудительное закрытие потоков
Добрый день, взял пример и немного под себя переделал, но не могу понять как остановить потоки, когда объект в каком - либо из них...

Закрытие потоков ввода/вывода
Почему закрытие потоков ввода/вывода в блоке finally считается плохой практикой ?

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

Закрытие всех безымянных потоков
Делаю небольшую игру в Unity3d, возникла необходимость создавать потоки без названий для каждого добавляемого объекта. static public void...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 31.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 31.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 30.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru