Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/18: Рейтинг темы: голосов - 18, средняя оценка - 4.67
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972

Корректно убить поток

21.10.2015, 09:42. Показов 3890. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пусть имеется поток thrdWork, который обрабатывает большие данные. В результате этой работы в памяти каждый раз сохраняются наиболее лучшие результаты. Т.к. эти результаты перезаписываются, то вывод их в файл возможен по окончанию обработки данных, что не реально долго (возможно и сутки, если не дольше). Поэтому я хочу выводить результаты по нажатию на клавишу (скажем мне будет достаточно того, что thrdWork уже нашел), но при этом дальнейшая обработка мне не нужна, т.е. поток нужно убить раньше времени. Я пришел к 2 решениям:

1 решение:
Кликните здесь для просмотра всего текста
C++
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
void Work()
{
   thread thrdWork(Processing);
   thrdWork.detach();
 
   char cmd;
 
   while (true) {
      cin >> cmd;
 
      if (cmd == 'd')
         // отладочная информация
         // сколько и с какими параметрами найдены
         writeDebugInfo();                
      else if (cmd == 'p') {
         writeBest();
         return;
      }
   }
}
 
 
//main
   thread thrd(Work);
   thrd.join();


и 2 способ:
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// main
 
   vector<thread> v_thrd;
   v_thread.push_back(thread(Processing)); // thrdWork
 
   char cmd;
 
   while (true) {
      cin >> cmd;
 
      if (cmd == 'd')
         // отладочная информация
         // сколько и с какими параметрами найдены
         writeDebugInfo();                
      else if (cmd == 'p') {
         writeBest();
         v_thrd.clear();
      }
   }


Какой метод более корректен или есть решение получше,
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
21.10.2015, 09:42
Ответы с готовыми решениями:

Можно ли убить поток (pthread) сигналом (kill()) ?
Процесс убивается вызовом kill(pid, 9); Как убить не весь процесс а только поток? Можно pthread_cancel + pthread_testcancel, но...

Можно ли убить поток зная лишь то что он запускается последним?
Подскажите пожалуйста Как убить поток в стороннем процессе? Нужно что бы получилось так что один процесс завершал один поток другого...

Сокеты и QThread - как корректно завершить поток
Пишу клиент с использованием QTcpSocket. Вынес разбор принимаемых сообщений в отдельный поток, но из-за заморочек с объектами qt никак не...

27
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
21.10.2015, 10:12
Никакой. Нельзя прерывать поток принудительно. Ты же не знаешь, на какой стадии он прервётся, может, и данные будут некорректные после этого. Используй средства синхронизации, чтобы поток сам завершался при определённых условиях.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
21.10.2015, 10:38  [ТС]
Цитата Сообщение от nmcf Посмотреть сообщение
может, и данные будут некорректные после этого
даже если они будут писаться в глобальные?
0
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
21.10.2015, 11:06
Дело не в глобальности, а в целостности. Например, 2 переменные запишет, а третью не успеет - она будет старое значение содержать и т. п.
1
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
21.10.2015, 11:12  [ТС]
Согласен. Тогда каждый раз буду опрашивать переменную, отвечающую за завершение потока.
0
2784 / 1937 / 570
Регистрация: 05.06.2014
Сообщений: 5,602
21.10.2015, 11:32
Если под Линуксом, то там есть pthread_cancel, вызывающий процесс схожий с броском исключения из вызванной в потоке cancellation point функции (без cancellation point не заработает). Под gcc этот "процесс" вроде как в исключение и преобразуется. Но вообще изврат, так как по сути выходит что сишные функции начинают плеваться исключениями.
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
21.10.2015, 11:34
Цитата Сообщение от mat_for_c Посмотреть сообщение
Тогда каждый раз буду опрашивать переменную, отвечающую за завершение потока.
Только не забудьте объявить ее как volatile.
0
 Аватар для mat_for_c
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
21.10.2015, 11:42  [ТС]
Цитата Сообщение от quwy Посмотреть сообщение
Только не забудьте объявить ее как volatile
Да, с эти я знаком уже
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.10.2015, 20:05
никак.
единственный способ потоку корректно завершиться - умереть естественной смертью.

обычно делают так: потоки у себя в каком то цикле крутятся,
и проверяют неккий атомарный флажок.

если true, значит хотят закрыть лавочку снаружи.
и поток корректно брякается из своей функции.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.10.2015, 16:33
Цитата Сообщение от quwy Посмотреть сообщение
Только не забудьте объявить ее как volatile.
Вы хотели сказать использовать атомики? Т.к. С++11 так не рекомендует делать.
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
22.10.2015, 17:08
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Вы хотели сказать использовать атомики?
Достаточно переменной. Это не совсем по канонам, но если булевую переменную изменяет только один поток, то кто и как бы не читал ее, рассинхронизации не произойдет. Самое худшее что может произойти -- ожидающий сигнала поток провернет один лишний цикл вместо того, чтобы завершиться немедленно. Но это только в том случае, если запись значения в эту переменную по каким-то невероятным причинам окажется не атомарной.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.10.2015, 17:20
Цитата Сообщение от quwy Посмотреть сообщение
рассинхронизации не произойдет.
Откуда такая уверенность?
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
22.10.2015, 17:28
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Откуда такая уверенность?
Оттуда, что иной сценарий видится мне совершенно невозможным.

У вас есть другое мнение? Пожалуйста, высказывайтесь.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.10.2015, 17:44
При использовании volatile в многопоточной среде никто ничего не гарантирует.
Более подробно смотрите cv (const and volatile) type qualifiers,Concurrency: Atomic and volatile in C++11 memory model
То что вы говорите это хаки завязанные на реализацию bool, volatile в конкретных компиляторах на конкретных архитектурах.
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
22.10.2015, 18:05
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
То что вы говорите это хаки завязанные на реализацию bool, volatile в конкретных компиляторах на конкретных архитектурах.
Я сразу сказал, что это не по канонам, но мы вроде об конкретном языке говорим, а не философствуем на тему? Данное решение работает, и является надежным. Можно конечно вместо нормального BOOL написать свой, который будет хранить один бит информации в килобайтном объекте, изменять его в течении миллиона тактов процессора, допускать неопределенные состояния и делать прочие непотребства. Но раз речь об относительно низкоуровневом языке, то по-умолчанию подразумевается работа с базовыми типами данных. В любой из существующих архитектур биты под BOOL либо все равны нулю, либо не все равны нулю, неопределенных состояний нет, а volatile не дает компилятору так или иначе запихнуть переменную в контекст потока. В результате atomic тут не обязателен и при этом, в отличие от volatile, доступен не во всех компиляторах (это к вопросу о привязке к компилятору).
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.10.2015, 18:20
Цитата Сообщение от quwy Посмотреть сообщение
volatile не дает компилятору так или иначе запихнуть переменную в контекст потока.
Дайте источник. Вы еще не учитываете, что у каждого ядра есть свой кеш, а volatile не гарантирует защиты от кеширования.

Цитата Сообщение от quwy Посмотреть сообщение
доступен не во всех компиляторах
Это в каких еще компиляторах нет атомарных переменных?
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
22.10.2015, 18:41
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Дайте источник.
Источник чего?

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Вы еще не учитываете, что у каждого ядра есть свой кеш, а volatile не гарантирует защиты от кеширования.
Кеш всех ядер всегда содержит актуальные данные. В противном случае постоянно наблюдались бы проблемы несогласованности состояний. Поток в любой момент может быть перемещен с одного ядра на другое (и это в реальных системах происходит достаточно часто). Представляете, что было бы, если бы такой поток начал читать данные из кеша одного ядра, а после перемещения продолжил бы читать более старую или более новую версию этих данных из кеша другого ядра? Согласованность данных в кешах строго обязательна для нормального функционирования системы.

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Это в каких еще компиляторах нет атомарных переменных?
В компиляторах для контроллеров, например.
0
1443 / 1326 / 131
Регистрация: 20.03.2009
Сообщений: 4,689
Записей в блоге: 11
22.10.2015, 19:02
Цитата Сообщение от quwy Посмотреть сообщение
Источник чего?
Источник на который вы опираетесь. Алена в свое время так же указала, что использование volatile.
Цитата Сообщение от quwy Посмотреть сообщение
Кеш всех ядер всегда содержит актуальные данные.
Как же.
Цитата Сообщение от quwy Посмотреть сообщение
В противном случае постоянно наблюдались бы проблемы несогласованности состояний
А они и наблюдаются, если нет синхронизации.

Цитата Сообщение от quwy Посмотреть сообщение
В компиляторах для контроллеров, например.
Атомики как правило реализуются в виде библиотеки, и сделать свой класс атомиков для контроллера не так уж и сложно.
0
Native x86
Эксперт Hardware
 Аватар для quwy
6853 / 3787 / 1024
Регистрация: 13.02.2013
Сообщений: 11,861
23.10.2015, 12:26
Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Источник на который вы опираетесь.
Документация по языку. Данное ключевое слово отбивает компилятору охоту оптимизировать доступ к переменной, и если написано if(a), то это всегда будет cmp [00ABCDEFh], 0 и je (или аналогичный по смыслу код), без перемещения переменной в регистр, вырезания проверок и т.п.

Что касается алениной информации о возможной неатомарности BOOL, то это, не имеет ни малейшего значения. Будь запись хоть сто раз не атомарной, все равно момент, когда переменная из "ноль" превращается в "не ноль", атомарен по определению.

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
А они и наблюдаются, если нет синхронизации.
О какой синхронизации речь? Я описал вам реальную ситуацию, когда даже однопотоковое приложение свалится, если кеши ядер не будут согласованы. Повторю еще раз: кеши ядер, которые кешируют пересекающиеся адреса, всегда согласованы, без этого система просто заглючит в первые же миллисекунды после запуска.

Цитата Сообщение от Dmitriy_M Посмотреть сообщение
Атомики как правило реализуются в виде библиотеки, и сделать свой класс атомиков для контроллера не так уж и сложно.
Но не всегда это нужно.
0
Эксперт С++
 Аватар для Avazart
8484 / 6151 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
27.10.2015, 18:34
Цитата Сообщение от quwy Посмотреть сообщение
Я сразу сказал, что это не по канонам,
Это заведомо глупый совет, освежите знания!

См. Архитектура многопоточного приложения, Нужно ли синхронизировать доступ к переменной из двух потоков?

Кстати в boost есть interupt() для прерывания.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
27.10.2015, 18:34
Помогаю со студенческими работами здесь

Как убить поток???
Добрый день всем! Подскажите пожалуйста, как убить поток, не дожидаясь окончания выполнения функции, связанной с ним???

Убить поток в адаптере
После Делфи не до конца понимаю работу &quot;сборщика мусора&quot; Явы. Привык &quot;подчищать&quot; за собой сам. Есть адаптер на основе...

убить поток + datagrid
на форме есть datagrid, каждая строка в нем создается из потока, так же из потока передается текущее состояние функции, запущенной в этом...

Убить спящий поток
Имеется 2 потока: t1 и t2. Внутри t1 выполнена команда t1.Sleep(int). После этого поток t2 хочет убить поток t1. Так, чтобы он умер и...

Как убить поток в CountDownTimer?
Привет, бойцам невидимого фронта! есть эдакий кастомный CountDownTimer.java: package com.dis.medprog; /* * Copyright (C)...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
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-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru