4 / 4 / 2
Регистрация: 24.05.2013
Сообщений: 300
1

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

07.06.2017, 00:22. Показов 2457. Ответов 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)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
07.06.2017, 00:22
Ответы с готовыми решениями:

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

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

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

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

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

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

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

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

Решение

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

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

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

Цитата Сообщение от Evgen8 Посмотреть сообщение
Просто гулять по всему списку потоков и пробуждать их все, чтобы они могли сами по флагу выйти - я не могу.
Значит, меняй архитектуру программы. Потому что иначе ничего не получится.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.06.2017, 09:40
Помогаю со студенческими работами здесь

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2023, CyberForum.ru