36 / 36 / 2
Регистрация: 28.04.2013
Сообщений: 110
|
|||||||||||
1 | |||||||||||
Многопоточность, выход из бесконечного цикла c++1103.06.2014, 23:06. Показов 5564. Ответов 70
Метки нет (Все метки)
Всем привет. Я в задачах многопоточности - новичок (начал ей заниматься буквально несколько часов назад), инфу искал, читал, но как-то пока не помогает.
Столкнулся с задачей (с++11 std::thread) код не оригинальный, а упрощённый, чтобы показать саму суть, подразумевается, что все необходимые include'ы уже есть. есть
Проблема: someThread не останавливает работу функции infinite. Цикл так и продолжает крутиться, выполняются do things и show window. Вопрос: Как завершить цикл ?
0
|
03.06.2014, 23:06 | |
Ответы с готовыми решениями:
70
Выход из бесконечного цикла Выход из бесконечного цикла по нажатию кнопки. Выход из бесконечного цикла Выход из бесконечного цикла |
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
04.06.2014, 20:47 | 21 |
По-вашему, volatile даёт компилятору возможность оптимизации по отношению к _stopCycle? А добавленнии паузы в main() такой возможности лишает?
Добавлено через 2 минуты С этим трудно спорить. Многопоточность, и одной ОС ведомо, как она распределит ресурс между потоками. Добавлено через 36 минут
0
|
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
|
|
04.06.2014, 20:47 | 22 |
volatile уж точно не даёт возможности оптимизации, а пауза только увеличивает до приемлемого уровня вероятность запустить второй поток раньше цикла в первом.
Что касается volatile, он заставляет заново перечитывать значение _stopCycle, и я слабо представляю в каких условиях на практике он здесь не будет работать, как задумано (наверное, это должна быть какая-то многопроцессорная система, где процессор, выполняющий второй поток не узнает вовремя об изменении _stopCycle в кэше процессора, выполняющего первый поток). В теории же, если не ошибаюсь, такой несинхронизированный доступ к не-atomic переменной - это ub.
0
|
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
|
|
04.06.2014, 21:10 | 24 |
Ну, там просто написано, что так не делают. Что касается стандарта, это в C++11, 1.10.0.21:
Добавлено через 3 минуты Насчёт оптимизации условия - да, это про зацикливание в коде ТС. Насчёт volatile - это про ошибочность использования volatile вместо std::atomic.
0
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
05.06.2014, 11:23 | 25 |
Утверждение об ошибочности основывается на том, что пишется по этой ссылке?
http://alenacpp.blogspot.ru/2006/04/volatile.html Добавлено через 13 часов 30 минут И в чём, собственно, ошибочность? Я применил volatile, чтобы исключить оптимизацию. Вы пишите: Значит, в этом отношении, ошибки применения нет? Насколько я понимаю, volatile и std::atomic это из разных областей, и для разного применяются.
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
05.06.2014, 12:19 | 26 |
А ничего, что пауза стоит после цикла и ни как на события до него влиять не может?
Добавлено через 8 минут Тебе надо не только отключить оптимизацию условия, но и гарантировать синхронизацию с первичным потоком, разделение флага между первичным и вторичным потоком, статичность/глобальность флага, то есть он должен существовать в одном и том же экземпляре для каждого экземпляра использующих его функций и фактическое существование флага в течении всего времени исполнения хотя бы одного потока. То есть флаг должен быть создан при старте первичного потока, так как он заведомо стартует первым и только после этого запускает вторичный, а освобождён при завершении того из двух потоков, который будет фактически завершён позже другого. Решает ли volatile все поставленные задачи?
0
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
||||||
05.06.2014, 13:01 | 27 | |||||
Разговор идёт о первом коде здесь: Многопоточность, выход из бесконечного цикла c++11
И вот об этой паузе:
0
|
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
|
|
05.06.2014, 13:12 | 28 |
bool по идее однобитный, что уже гарантирует синхронизацию и исключает необходимость мьютексов, так как ни одна операция с отдельным битом не может быть прервана. Но по стандарту bool может быть чем угодно, лишь бы поддерживал два значения, понятные циклам с условием и условному оператору и допускал приведение к нему всего, что к нему должно приводиться, а в силу особенностей адресации фактическая разрядность кратна байту. Есть ещё такой нюанс: битовые операции в большинстве камней вообще не реализованы непосредственно, а реализуются с помощью масок, а загрузка маски в регистр - отдельная операция, тогда операция с упакованным флагом оказывается составной и может быть прервана. Но если остальные биты ни кого не интересуют, то можно выполнить операцию сразу с байтом/словом, которая уже не может быть прервана, если только не реализована через другую разрядность на RISC-камне, чья RISCковость явна и существует на логическом уровне, а не только на уровне ядра процессора.
0
|
Master of Orion
|
||||||
05.06.2014, 13:21 | 29 | |||||
Ребят, я в плюсах не оч шарю, но так вроде должно работать без проблем?..
taras atavin, bool как правило является int-ом из-за проблем с выравниванием памяти и прочими прелестями. В лучшем случае он однобайтный. Но однобитных булов вообще не бывает афайк. Добавлено через 1 минуту volatile отвечает только за отсутствие кэширования значения переменной, за его использование как средства синхронизации со ссылкой на стандарты и пр следует отрывать руки.
0
|
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
|
|
05.06.2014, 14:06 | 32 |
В этом отношении ошибки нет. Но volatile изначально был введён для работы с отображёнными на память устройствами ввода-вывода. C++98 ничего не говорил о многопоточности, так что volatile был лучше, чем ничего; к тому же MS в своих компиляторах наделил его дополнительным смыслом (acquire/release semantics), которого нет в стандарте. В C++11 решили ничего нового для volatile не придумывать, и просто добавили atomic типы.
atomic также решает и вопросы синхронизации, и в зависимости от платформы реализация может быть от простых чтения/записи до использования мьютексов.
0
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
05.06.2014, 14:12 | 33 |
Где здесь про то, что volatile синхронизирует?
И...? Где в вашем коде, вообще, второй поток? Как проверять будет зацикливание или нет? Этот код про то, как избежать зацикливания? Или про что? Добавлено через 5 минут С этим никто не спорит. Но можно использовать volatile, и мьютексы для синхронизации, т.е., не заменять, в моём коде, volatile на atomic, а добавить мьютексы. Как вариант?
0
|
Master of Orion
|
|
05.06.2014, 14:22 | 34 |
0
|
2835 / 1644 / 254
Регистрация: 03.12.2007
Сообщений: 4,222
|
|
05.06.2014, 14:22 | 35 |
Раз тут пошёл виндовый код: в таком случае можно LONG вместо bool и InterlockedCompareExchange.
Да.
1
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
||||||
05.06.2014, 14:31 | 37 | |||||
bool и volatile, по-вашему, это одинаковые слова?
Где они в вашем коде? Код зацикливается совсем по другой причине (так же как и ваш, если не добавить паузу перед циклом в основном потоке). Добавлено через 2 минуты Узнаёте ваш класс? Зацикливает.
0
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
05.06.2014, 15:03 | 39 |
По-вашему, я придумываю? Вот здесь почитайте: Многопоточность, выход из бесконечного цикла c++11
0
|
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
|
|
05.06.2014, 15:17 | 40 |
Неправильность этого кода в том, что нет ничего, чтобы гарантировало выполнение функции inifiniteWhile() во втором потоке раньше, чем вызов функции stop() в основном потоке.
Вот здесь, во втором коде, такая гарантия сделана: Многопоточность, выход из бесконечного цикла c++11
1
|
05.06.2014, 15:17 | |
05.06.2014, 15:17 | |
Помогаю со студенческими работами здесь
40
Выход из бесконечного цикла Выход из бесконечного цикла Выход из бесконечного цикла Выход из бесконечного цикла программно Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |