Size: a a a

2020 March 19

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
Любой wait без таймаута в многопоточной среде должен вызывать напряжение булок и повышенное внимание. Ибо - источник дедлоков и багов.
А какой должен быть таймаут и реакция на него?
источник

FF

Flex Ferrum in pro.cxx
Побитый Кирпич
А какой должен быть таймаут и реакция на него?
Зависит от логики в конкретном месте.
источник

DF

Dollar Føølish in pro.cxx
Ну вот очередь допустим
источник

DF

Dollar Føølish in pro.cxx
Там стоит  на кондваре консьюмер
источник

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
Зависит от логики в конкретном месте.
Просто такой таймаут выглядит как:
bool b = true;
if (b != true) {
// а вдруг
}
источник

DF

Dollar Føølish in pro.cxx
Что ему делать вне вейта?
источник

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
Зависит от логики в конкретном месте.
cond_var это низкоуровневый примитив, а знание о таймауте обычно лежит в высокоуровневом коде. Поэтому timed_wait это редкий юзкейс. Обычно таймауты обрабатывают через тот же notify с обычным wait-ом
источник

FF

Flex Ferrum in pro.cxx
Побитый Кирпич
cond_var это низкоуровневый примитив, а знание о таймауте обычно лежит в высокоуровневом коде. Поэтому timed_wait это редкий юзкейс. Обычно таймауты обрабатывают через тот же notify с обычным wait-ом
В разных командах - разные обычаи. Скажем, если в команде принято для контроля жизни потоков использовать (shared) cancellation-токены со своей логикой (или stop-токены с jthread Джойсаттиса), то становится всё сильно интереснее. В примере prod-cons выше легко наступить на ситуацию, когда в stop _не_ поднимается флаг "в очереди есть данные!", чтобы консьюмеры перестали ждать и ушли на проверку, что надо останавливаться. И консьюмеры не останавливаются. А это - само по себе размывание ответственности. В итоге код обрастает тайными знаниями в стиле "а вот эти флаги мы используем для этого, этого, а ещё этого, поэтому модифицируем их под общими мутексами даже там, где в этом нет очевидного смысла". Ну а на кондварах ждут без таймаутов, да. :)
источник

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
В разных командах - разные обычаи. Скажем, если в команде принято для контроля жизни потоков использовать (shared) cancellation-токены со своей логикой (или stop-токены с jthread Джойсаттиса), то становится всё сильно интереснее. В примере prod-cons выше легко наступить на ситуацию, когда в stop _не_ поднимается флаг "в очереди есть данные!", чтобы консьюмеры перестали ждать и ушли на проверку, что надо останавливаться. И консьюмеры не останавливаются. А это - само по себе размывание ответственности. В итоге код обрастает тайными знаниями в стиле "а вот эти флаги мы используем для этого, этого, а ещё этого, поэтому модифицируем их под общими мутексами даже там, где в этом нет очевидного смысла". Ну а на кондварах ждут без таймаутов, да. :)
В высокоуровневом коде вообще нет кондваров. А в низкоуровневом нет знания о таймаутах
источник

FF

Flex Ferrum in pro.cxx
Побитый Кирпич
В высокоуровневом коде вообще нет кондваров. А в низкоуровневом нет знания о таймаутах
И всё оно как-то само собой потухает и останавливается. Ага. :)
источник

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
И всё оно как-то само собой потухает и останавливается. Ага. :)
Суть в том, что таймаут это workaround бага. Типа если вдруг у нас там баг, то мы остановимся через 5 минут (ага, а почему 5?). Но реакция на баг должна быть не в workaround-е, а в фиксе бага
источник

ПК

Побитый Кирпич in pro.cxx
В программе без бага всё само останавливается, да
источник

FF

Flex Ferrum in pro.cxx
Побитый Кирпич
Суть в том, что таймаут это workaround бага. Типа если вдруг у нас там баг, то мы остановимся через 5 минут (ага, а почему 5?). Но реакция на баг должна быть не в workaround-е, а в фиксе бага
Нет. В моей реальности таймауты здесь - это способ недопустить бага. Вот у нас есть примитив, по которому мы останавливаемся. Мы его проверяем (с заданной регулярностью). Вот тут есть примитив, на котором мы ждём. Но ждём не бесконечно, а столько, чтобы регулярно проверять другой примитив. И т. д. Модели могут быть разные, но суть - одна. И вот _тогда_ багов нет, и всё останавливается. А: "так, у нас тут очередь, а там там - кондвар на ожидание, давайте мы сделаем так, что если кондвар нотифицирован, а очередь пуста - это значит, что надо останавливаться" - как раз таки путь к багам.
источник

FF

Flex Ferrum in pro.cxx
Альтернативный подход, но в ту же сторону: https://github.com/josuttis/jthread/tree/master/doc
источник

FF

Flex Ferrum in pro.cxx
Интересный пропозал.
источник

ПК

Побитый Кирпич in pro.cxx
Flex Ferrum
Интересный пропозал.
cancellation_token это как раз правильный способ отмены задач
источник

FF

Flex Ferrum in pro.cxx
Побитый Кирпич
cancellation_token это как раз правильный способ отмены задач
Да. Но он не всегда сочетается с бесконечными wait'ами на кондварах (стандартных, разумеется). О чём я и говорю. Если заглянуть в пропозал выше - там предлагается допилить condvar так, чтобы ему можно было явно cancellation token вдвинуть, а дальше начнётся подковёрная магия.
источник

CD

Constantine Drozdov in pro.cxx
Flex Ferrum
Любой wait без таймаута в многопоточной среде должен вызывать напряжение булок и повышенное внимание. Ибо - источник дедлоков и багов.
Ну неееет, если wait это ожидание выполнения выполненной пересылки, как это и должно быть
источник

CD

Constantine Drozdov in pro.cxx
То есть wait это всегда ожидание выполнения синхронизации между потоками
источник

FF

Flex Ferrum in pro.cxx
Constantine Drozdov
Ну неееет, если wait это ожидание выполнения выполненной пересылки, как это и должно быть
Я достиг достаточного уровня MT-паранои, при котором считаю, что любой wait без таймаута может оказаться бесконечным и привести к проблемам. :) Меня можно попробовать убедить в обратном, но меньшим параноиком (в этой части) я не стану.
источник