Давайте рассмотрим что-то вроде приложения с графическим интерфейсом, в котором основной поток обновляет интерфейс практически мгновенно, а другой поток опрашивает данные по сети или что-то, что гарантированно займет 5-10 секунд для завершения работы.
Я получил много разных ответов на это, но некоторые люди говорят, что если это условие гонки статистической невозможности, не беспокойтесь об этом вообще, но другие говорили, что если есть даже 10 -53 % (я шучу вы не о числах, это то, что я слышал) о магии вуду, происходящей из-за состояния гонки, всегда получайте / снимайте блокировки в потоке, который в этом нуждается.
о чем ты думаешь? Это хорошая практика программирования для обработки состояния гонки в таких статистически невозможных ситуациях? или было бы совершенно ненужным или даже контрпродуктивным добавлять больше строк кода, чтобы препятствовать удобочитаемости?
Ответы:
Если это действительно событие типа 1 в 10 ^ 55, не было бы необходимости кодировать его. Это будет означать, что если вы выполняете операцию 1 миллион раз в секунду, вы будете получать одну ошибку каждые 3 * 10 ^ 41 года, что примерно в 10 ^ 31 раз больше возраста вселенной. Если ваше приложение имеет ошибку только один раз в каждом триллионе триллионов миллиардов возрастов вселенной, это, вероятно, достаточно надежно.
Тем не менее, я бы очень сильно поспорил, что ошибка далеко не так маловероятна. Если вы можете представить себе ошибку, то почти наверняка она произойдет хотя бы изредка, поэтому стоит начать с правильного ее кодирования. Кроме того, если вы правильно кодируете потоки с самого начала, чтобы они получали и снимали блокировки соответствующим образом, код в будущем станет гораздо более обслуживаемым. Вам не нужно беспокоиться, когда вы вносите изменения, что вы должны повторно проанализировать все потенциальные условия гонки, пересчитать их вероятности и убедиться, что они не повторится.
источник
С точки зрения затрат и выгод вы должны писать дополнительный код только тогда, когда он приносит вам достаточную выгоду.
Например, если худшее, что могло бы произойти, если неправильная нить «выиграет гонку», это то, что информация не будет отображаться, и пользователь должен будет нажать «обновить», не беспокойтесь о защите от состояния гонки: необходимость писать много кода не стоит, чтобы исправить что-то незначительное.
С другой стороны, если условие гонки может привести к неправильным переводам денег между банковскими счетами, вы должны принять меры против состояния гонки независимо от того, сколько кода вам нужно написать, чтобы решить эту проблему.
источник
Найти условие гонки - сложная часть. Вы, вероятно, потратили почти столько же времени на написание этого вопроса, сколько потребовалось бы для его устранения. Это не так, что делает его намного менее читабельным. Программисты ожидают увидеть код синхронизации в таких ситуациях, и на самом деле могут потратить больше времени на размышления о том, почему его нет и если его добавление исправит их несвязанную ошибку.
Что касается вероятностей, вы будете удивлены. В прошлом году у меня был отчет об ошибке состояния гонки, который я не мог воспроизвести с помощью тысяч автоматических попыток, но одна система одного клиента видела его постоянно. Экономическая целесообразность тратить 5 минут на ее устранение в настоящее время, в отличие от возможного устранения «невозможной» ошибки при установке клиента, делает выбор несложным.
источник
Получить и отпустить замки. Вероятности меняются, алгоритмы меняются. Это плохая привычка, и когда что-то идет не так, вам не нужно останавливаться и задумываться, не ошиблись ли вы шансы ...
источник
Пока кто-то не введет слой кэширования для повышения производительности. Внезапно, что другой шаг закончился почти мгновенно, и состояние гонки проявляется чаще, чем нет.
Если бы это произошло несколько недель назад, потребовалось около 2 дней на то, чтобы найти ошибку.
Всегда устанавливайте условия гонки, если вы их узнаете.
источник
Простое против правильного.
Во многих случаях простота превосходит правильность. Это вопрос стоимости.
Кроме того, условия гонки - это неприятные вещи, которые не подчиняются простой статистике. Все идет хорошо, пока какая-то другая, казалось бы, не связанная синхронизация не вызовет внезапное возникновение состояния вашей гонки в половине случаев. Если, конечно, вы не включите логи или не отладите код.
Прагматичной альтернативой предотвращению состояния гонки (которое может быть сложным) может быть обнаружение и регистрация его (бонус за неудачный и ранний отказ). Если этого никогда не произойдет, вы мало что потеряли. Если это действительно происходит, у вас есть веское основание тратить дополнительное время на его исправление.
источник
Если ваше состояние гонки связано с безопасностью, вы всегда должны писать код, чтобы предотвратить это.
Типичным примером являются условия гонки с созданием / открытием файлов в Unix, которые в некоторых случаях могут привести к атакам с повышением привилегий, если программа с условием гонки выполняется с более высокими привилегиями, чем пользователь, взаимодействующий с ней, такой как процесс системного демона или еще хуже ядро.
Даже если у расы есть случайный случайный случай в 10 ^ (- 80) , вполне вероятно, что решительный злоумышленник имеет приличный шанс создать такие условия преднамеренно и искусственно.
источник
Therac-25!
Разработчики проекта Therac-25 были довольно уверены в выборе времени между пользовательским интерфейсом и проблемой интерфейса в терапевтическом аппарате XRAY.
Они не должны были быть.
Вы можете узнать больше об этой известной программной катастрофе «жизнь и смерть» по адресу:
http://www.youtube.com/watch?v=izGSOsAGIVQ
или же
http://en.wikipedia.org/wiki/Therac-25
Ваше приложение может быть гораздо менее чувствительным к сбоям, чем медицинские устройства. Полезным методом является оценка подверженности риску как продукта вероятности возникновения и стоимости возникновения в течение срока службы продукта для всех единиц, которые могут быть произведены.
Если вы решили построить свой код так, чтобы он работал долго (и это звучит так, как будто вы это сделали), вам следует учитывать закон Мура, который может легко отбрасывать несколько нулей каждые несколько лет, поскольку компьютеры внутри или вне вашей системы работают быстрее. Если вы отправите тысячи копий, отбросьте больше нулей. Если пользователи выполняют эту операцию ежедневно (или ежемесячно) в течение многих лет, отнимите еще несколько. Если он используется там, где доступно волокно Google, что тогда? Если мусор UI собирает середину работы GUI, это влияет на гонку? Вы используете библиотеку с открытым исходным кодом или Windows за вашим графическим интерфейсом? Могут ли обновления там повлиять на время?
Семафоры, блокировки, мьютексы, барьерная синхронизация являются одними из способов синхронизации действий между потоками. Потенциально, если вы их не используете, другой человек, который поддерживает вашу программу, может, а затем довольно быстро предположить, что отношения между потоками могут измениться, и вычисление о состоянии гонки может быть признано недействительным.
Я рекомендую вам явно синхронизировать, потому что, хотя вы, возможно, никогда не увидите, что это создает проблему, клиент может. Кроме того, даже если состояние вашей гонки никогда не наступит, что делать, если вы или ваша организация вызваны в суд для защиты вашего кода (поскольку Toyota была связана с Prius несколько лет назад). Чем тщательнее методология, тем лучше. Возможно, было бы лучше сказать «мы защищаемся от такого маловероятного случая, как этот ...», чем сказать «мы знаем, что наш код потерпит неудачу, но мы записали это уравнение, чтобы показать, что этого не произойдет при нашей жизни. Вероятно. "
Похоже, что расчет вероятности исходит от кого-то еще. Знают ли они ваш код, и знаете ли вы их достаточно, чтобы поверить, что ошибки не было? Если бы я вычислил надежность 99,99999% для чего-то, я мог бы также вспомнить свои занятия по статистике в колледже и вспомнить, что я не всегда получал 100%, и отбросил немало процентов на мои собственные оценки надежности.
источник
Простота хороша только тогда, когда это правильно. Поскольку этот код неверен, будущие программисты неизбежно будут смотреть на него при поиске связанной ошибки.
Независимо от того, как вы справляетесь с этим (регистрируя его, документируя или добавляя блокировки - это зависит от стоимости), вы сэкономите время других программистов при просмотре кода.
источник
Это будет зависеть от контекста. Если это обычная игра для iPhone, то, вероятно, нет. Система управления полетом для следующего пилотируемого космического корабля, вероятно. Все зависит от того, каковы будут последствия, если «плохой» результат будет измеряться в сравнении с предполагаемой стоимостью его исправления.
Для этих типов вопросов редко существует ответ «один размер подходит всем», потому что это не вопросы программирования, а вопросы экономики.
источник
Да, ожидайте неожиданного. Я провел часы (в коде других людей ^^), отслеживая условия, которые никогда не должны происходить.
Такие вещи, как всегда есть else, всегда имеют значение по умолчанию для case, инициализируют переменные (да, действительно .. ошибки происходят из-за этого), проверяют ваши циклы на повторное использование переменных для каждой итерации и т. Д.
Если вы беспокоитесь о проблемах с потоками, читайте блоги, статьи и книги на эту тему. Нынешняя тема представляется неизменными данными.
источник
Просто исправь это.
Я видел именно это. Одному потоку удается выполнить сетевой запрос к серверу, который выполняет сложный поиск в базе данных и отвечает до того, как другой поток перешел к следующей строке кода. Такое случается.
Какой-то клиент где-нибудь решит однажды запустить что-то, что потребляет все процессорное время для «быстрого» потока, оставляя медленный поток запущенным, и вы пожалеете :)
источник
Если вы узнали о маловероятном состоянии гонки, хотя бы запишите это в коде!
РЕДАКТИРОВАТЬ: я должен добавить, что я бы исправить это, если это вообще возможно, но на момент написания выше ни один другой ответ явно сказал, по крайней мере документировать проблему в коде.
источник
Я думаю, что, если вы уже знаете, как и почему это может произойти, с таким же успехом можно справиться с этим. То есть если он не отнимает много ресурсов.
источник
Все зависит от того, каковы последствия состояния гонки. Я думаю, что люди, отвечающие на ваш вопрос, подходят для своей работы. У меня есть двигатели конфигурации маршрутизатора. Для меня гоночные условия либо заставляют системы стоять на месте, поврежденные или ненастроенные, даже несмотря на то, что это говорит об успешности. Я всегда использую семафоры для каждого маршрутизатора, поэтому мне не нужно ничего чистить вручную.
Я думаю, что некоторые из моего кода GUI по-прежнему подвержены условиям гонки, так что пользователю может быть выдана ошибка, потому что произошло состояние гонки, но у меня не было бы таких возможностей, если есть вероятность повреждения данных или неправильного поведения пользователя. приложение после такого события.
источник
Как ни странно, я недавно столкнулся с этой проблемой. Я даже не осознавал, что условия гонки возможны в моих обстоятельствах. Состояние гонки появилось только тогда, когда многоядерные процессоры стали нормой.
Сценарий был примерно таким. Драйвер устройства вызвал события для программного обеспечения для обработки. Контроль должен был вернуться к драйверу устройства как можно скорее, чтобы предотвратить тайм-аут на устройстве. Для этого событие было записано и поставлено в очередь в отдельном потоке.
Это работало хорошо в течение многих лет. Тогда вдруг произойдет сбой в определенных конфигурациях. Оказывается, что поток очереди теперь работал действительно параллельно с потоком обработки событий, а не разделял время одного процессора. Ему удалось отправить следующую команду на устройство до того, как событие было подтверждено, что вызвало ошибку вне последовательности.
Учитывая, что это затронуло только одного клиента в одной конфигурации, я постыдно указал,
Thread.Sleep(1000)
где была проблема. С тех пор проблем не было.источник