223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
|
|||||||||||
1 | |||||||||||
Корректно убить поток21.10.2015, 09:42. Показов 3407. Ответов 27
Метки нет (Все метки)
Пусть имеется поток thrdWork, который обрабатывает большие данные. В результате этой работы в памяти каждый раз сохраняются наиболее лучшие результаты. Т.к. эти результаты перезаписываются, то вывод их в файл возможен по окончанию обработки данных, что не реально долго (возможно и сутки, если не дольше). Поэтому я хочу выводить результаты по нажатию на клавишу (скажем мне будет достаточно того, что thrdWork уже нашел), но при этом дальнейшая обработка мне не нужна, т.е. поток нужно убить раньше времени. Я пришел к 2 решениям:
1 решение: Кликните здесь для просмотра всего текста
и 2 способ: Кликните здесь для просмотра всего текста
Какой метод более корректен или есть решение получше,
0
|
21.10.2015, 09:42 | |
Ответы с готовыми решениями:
27
Можно ли убить поток (pthread) сигналом (kill()) ? Можно ли убить поток зная лишь то что он запускается последним? Сокеты и QThread - как корректно завершить поток Как убить поток??? |
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
|
|
21.10.2015, 10:12 | 2 |
Никакой. Нельзя прерывать поток принудительно. Ты же не знаешь, на какой стадии он прервётся, может, и данные будут некорректные после этого. Используй средства синхронизации, чтобы поток сам завершался при определённых условиях.
0
|
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
|
|
21.10.2015, 10:38 [ТС] | 3 |
0
|
7793 / 6560 / 2984
Регистрация: 14.04.2014
Сообщений: 28,672
|
|
21.10.2015, 11:06 | 4 |
Дело не в глобальности, а в целостности. Например, 2 переменные запишет, а третью не успеет - она будет старое значение содержать и т. п.
1
|
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
|
|
21.10.2015, 11:12 [ТС] | 5 |
Согласен. Тогда каждый раз буду опрашивать переменную, отвечающую за завершение потока.
0
|
2782 / 1935 / 570
Регистрация: 05.06.2014
Сообщений: 5,600
|
|
21.10.2015, 11:32 | 6 |
Если под Линуксом, то там есть pthread_cancel, вызывающий процесс схожий с броском исключения из вызванной в потоке cancellation point функции (без cancellation point не заработает). Под gcc этот "процесс" вроде как в исключение и преобразуется. Но вообще изврат, так как по сути выходит что сишные функции начинают плеваться исключениями.
0
|
223 / 213 / 80
Регистрация: 26.04.2013
Сообщений: 972
|
|
21.10.2015, 11:42 [ТС] | 8 |
0
|
8739 / 4317 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
|
|
21.10.2015, 20:05 | 9 |
никак.
единственный способ потоку корректно завершиться - умереть естественной смертью. обычно делают так: потоки у себя в каком то цикле крутятся, и проверяют неккий атомарный флажок. если true, значит хотят закрыть лавочку снаружи. и поток корректно брякается из своей функции.
0
|
Native x86
5514 / 3273 / 934
Регистрация: 13.02.2013
Сообщений: 10,425
|
|
22.10.2015, 17:08 | 11 |
Достаточно переменной. Это не совсем по канонам, но если булевую переменную изменяет только один поток, то кто и как бы не читал ее, рассинхронизации не произойдет. Самое худшее что может произойти -- ожидающий сигнала поток провернет один лишний цикл вместо того, чтобы завершиться немедленно. Но это только в том случае, если запись значения в эту переменную по каким-то невероятным причинам окажется не атомарной.
0
|
22.10.2015, 17:44 | 14 |
При использовании volatile в многопоточной среде никто ничего не гарантирует.
Более подробно смотрите cv (const and volatile) type qualifiers,Concurrency: Atomic and volatile in C++11 memory model То что вы говорите это хаки завязанные на реализацию bool, volatile в конкретных компиляторах на конкретных архитектурах.
0
|
Native x86
5514 / 3273 / 934
Регистрация: 13.02.2013
Сообщений: 10,425
|
|
22.10.2015, 18:05 | 15 |
Я сразу сказал, что это не по канонам, но мы вроде об конкретном языке говорим, а не философствуем на тему? Данное решение работает, и является надежным. Можно конечно вместо нормального BOOL написать свой, который будет хранить один бит информации в килобайтном объекте, изменять его в течении миллиона тактов процессора, допускать неопределенные состояния и делать прочие непотребства. Но раз речь об относительно низкоуровневом языке, то по-умолчанию подразумевается работа с базовыми типами данных. В любой из существующих архитектур биты под BOOL либо все равны нулю, либо не все равны нулю, неопределенных состояний нет, а volatile не дает компилятору так или иначе запихнуть переменную в контекст потока. В результате atomic тут не обязателен и при этом, в отличие от volatile, доступен не во всех компиляторах (это к вопросу о привязке к компилятору).
0
|
22.10.2015, 18:20 | 16 |
Дайте источник. Вы еще не учитываете, что у каждого ядра есть свой кеш, а volatile не гарантирует защиты от кеширования.
Это в каких еще компиляторах нет атомарных переменных?
0
|
Native x86
5514 / 3273 / 934
Регистрация: 13.02.2013
Сообщений: 10,425
|
|
22.10.2015, 18:41 | 17 |
Источник чего?
Кеш всех ядер всегда содержит актуальные данные. В противном случае постоянно наблюдались бы проблемы несогласованности состояний. Поток в любой момент может быть перемещен с одного ядра на другое (и это в реальных системах происходит достаточно часто). Представляете, что было бы, если бы такой поток начал читать данные из кеша одного ядра, а после перемещения продолжил бы читать более старую или более новую версию этих данных из кеша другого ядра? Согласованность данных в кешах строго обязательна для нормального функционирования системы. В компиляторах для контроллеров, например.
0
|
Native x86
5514 / 3273 / 934
Регистрация: 13.02.2013
Сообщений: 10,425
|
|
23.10.2015, 12:26 | 19 |
Документация по языку. Данное ключевое слово отбивает компилятору охоту оптимизировать доступ к переменной, и если написано if(a), то это всегда будет cmp [00ABCDEFh], 0 и je (или аналогичный по смыслу код), без перемещения переменной в регистр, вырезания проверок и т.п.
Что касается алениной информации о возможной неатомарности BOOL, то это, не имеет ни малейшего значения. Будь запись хоть сто раз не атомарной, все равно момент, когда переменная из "ноль" превращается в "не ноль", атомарен по определению. О какой синхронизации речь? Я описал вам реальную ситуацию, когда даже однопотоковое приложение свалится, если кеши ядер не будут согласованы. Повторю еще раз: кеши ядер, которые кешируют пересекающиеся адреса, всегда согласованы, без этого система просто заглючит в первые же миллисекунды после запуска. Но не всегда это нужно.
0
|
27.10.2015, 18:34 | 20 |
Это заведомо глупый совет, освежите знания!
См. Архитектура многопоточного приложения, Нужно ли синхронизировать доступ к переменной из двух потоков? Кстати в boost есть interupt() для прерывания.
0
|
27.10.2015, 18:34 | |
27.10.2015, 18:34 | |
Помогаю со студенческими работами здесь
20
Убить поток в адаптере убить поток + datagrid Убить спящий поток Как убить поток в CountDownTimer? Убить поток, выполняющий задачу Не получается убить поток сервера Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |