Как я взломал Starbucks для безлимитного кофе. Состояние гонки


multithreading - Что такое состояние гонки?

Существует важное техническое различие между условиями гонки и гонками данных. Большинство ответов, похоже, делают предположение, что эти термины эквивалентны, но они не являются.

Голосование данных происходит, когда 2 команды обращаются к одному и тому же месту памяти, по крайней мере один из этих обращений является записью, и нет необходимости до упорядочивания между этими обращениями. Теперь то, что происходит, происходит до заказа, подвержено большому количеству дебатов, но в целом пары блокировки улоков на одной и той же переменной блокировки и пар сигнала ожидания при одной и той же переменной условия вызывают случайный порядок.

Состояние гонки - это семантическая ошибка. Это недостаток, связанный с синхронизацией или упорядочением событий, что приводит к ошибочному поведению программы.

Многие условия гонки могут (и на самом деле) вызваны гонками данных, но это необязательно. На самом деле, расы данных и условия гонки не являются ни необходимым, ни достаточным условием для друг друга. Это сообщение в блоге также объясняет разницу очень хорошо, с простым примером банковских транзакций. Вот еще один простой пример , который объясняет разницу.

Теперь, когда мы применили терминологию, попробуем ответить на исходный вопрос.

Учитывая, что условия гонки являются семантическими ошибками, нет общего способа их обнаружения. Это связано с тем, что нет способа автоматизированного оракула, который может отличить правильное и неправильное поведение программы в общем случае. Обнаружение гонки - неразрешимая проблема.

С другой стороны, расы данных имеют точное определение, которое не обязательно связано с правильностью, и поэтому их можно обнаружить. Существует множество разновидностей детекторов гонки данных (статическое/динамическое обнаружение гонки данных, обнаружение гонки данных на основе блокировки, обнаружение на основе данных на основе ранее обнаруженных данных, обнаружение гибридных данных). Современный динамический детектор гонки данных ThreadSanitizer, который на практике работает очень хорошо.

Обработка расчётов данных в общем требует некоторой дисциплины программирования, чтобы вызвать это - перед ребрами между обращениями к общим данным (либо во время разработки, либо после их обнаружения с использованием вышеупомянутых инструментов). это можно сделать с помощью блокировок, переменных условий, семафоров и т.д. Однако можно также использовать разные парадигмы программирования, такие как передача сообщений (вместо общей памяти), которые предотвращают расследование данных по построению.

qaru.site

гонки потоков и Atomics / Блог компании RUVDS.com / Хабр

→ ArrayBuffer и SharedArrayBuffer в JavaScript, часть 1: краткий курс по управлению памятью → ArrayBuffer и SharedArrayBuffer в JavaScript, часть 2: знакомство с новыми объектами языка → ArrayBuffer и SharedArrayBuffer в JavaScript, часть 3: гонки потоков и Atomics

В прошлый раз, рассматривая SharedArrayBuffer, мы говорили о том, что работа с этим объектом может привести к состоянию гонки потоков. Это усложняет разработку, поэтому мы ожидаем, что этим средством будут пользоваться создатели библиотек, имеющие опыт в многопоточном программировании. Они смогут применить новые низкоуровневые API для создания высокоуровневых инструментов, с которыми будут работать обычные программисты, не касаясь ни SharedArrayBuffer, ни Atomics.SharedArrayBuffer и Atomics как основа реализации многопоточности в JS-библиотеках и WebAssembly

Если вы не относитесь к разработчикам библиотек, то, вероятнее всего, работать напрямую с Atomics и SharedArrayBuffer вам не следует. Однако, полагаем, вам будет интересно узнать, как всё это устроено. Поэтому в данном материале мы поговорим о состояниях гонок потоков, которые могут возникать при многопоточном программировании, и о том, как использование объекта Atomics поможет библиотекам, основанным на новых средствах JS, этих состояний избежать.

Начнём с более подробного разговора о том, что же такое гонка потоков.

Гонка потоков: классический пример

Состояние гонки потоков может возникнуть в ситуации, когда имеется переменная, доступ к которой есть у двух потоков. Предположим, первый поток, основываясь на значении переменной fileExists, загружает некий файл, а второй проверяет, существует ли файл, и, если это так, устанавливает эту переменную в значение true. В детали мы не вдаёмся, код проверки наличия файла опущен.

Изначально переменная, которую процессы используют для обмена данными, установлена в значение false.

Первый поток, слева, загружает файл, если переменная fileExists установлена в true, второй поток, после проверки существования файла, устанавливает эту переменную в true

Если код во втором потоке будет выполнен первым, установит переменную в true, первый поток загрузит файл.

Сначала второй поток устанавливает переменную в значение true, потом второй поток загружает файл

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

Если сначала, когда переменная ещё установлена в false, выполняется код в первом потоке, выводится сообщение об ошибке

На самом же деле проблема заключается не в том, что файл найти не удалось. В нашем, весьма упрощённом случае, настоящая причина сообщения об ошибке — состояние гонки потоков.

Многие JS-разработчики сталкиваются с состоянием гонки такого рода даже в однопоточном коде. И, на самом деле, не нужно ничего знать о многопоточности для того, чтобы увидеть, почему возникают подобные ошибки.

Однако, существуют некоторые виды гонок потоков, которые невозможны в однопоточном коде, но могут возникать при разработке многопоточных программ, потоки которых пользуются общей памятью.

Различные виды гонок потоков и Atomics

Поговорим о различных видах гонок потоков, с которыми можно столкнуться в многопоточном коде, и о том, как Atomics может помочь их предотвратить. Надо отметить, что тут мы не стремимся рассмотреть абсолютно все возможные состояния гонок, но этот обзор поможет вам понять, зачем те или иные методы предусмотрены в API Atomics.

Прежде чем мы начнём, хотелось бы снова напомнить, обращаясь к обычным разработчикам, что не ожидается, что они будут напрямую использовать возможности Atomics. Многопоточная разработка отличается повышенной сложностью, мы полагаем, что новыми средствами JavaScript будут, в основном, пользоваться создатели библиотек.Многопоточное программирование таит в себе множество опасностей

Теперь приступим к рассказу о состояниях гонок.

Гонка потоков при обработке отдельной операции

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

Два потока поочерёдно инкрементируют переменную

Хотя, в JS-программе, инкрементирование выглядит как одна операция, если взглянуть на скомпилированный код, окажется, что перед нами несколько операций. Процессору, для инкрементирования переменной, надо выполнить три операции.

Дело тут в том, что у компьютера имеются разные виды памяти. В данном случае речь идёт об обычной оперативной памяти, которая хранит данные сравнительно длительное время, и о регистрах процессора, которые используются для кратковременного хранения данных.

Оперативная память, регистры процессора и арифметико-логическое устройство

Наши два потока обладают общей оперативной памятью, но не регистрами процессора. Каждому потоку, для выполнения неких действий с данными, нужно сначала перенести их из оперативной памяти в регистры. Затем — выполнить вычисления, а уже после этого — вернуть данные обратно в оперативную память.

Выполнение действий с данными, хранящимися в оперативной памяти. Первый шаг — загрузка данных из памяти в регистр. Второй — выполнение вычислений. Третий — сохранение результата вычислений в оперативной памяти

Если все необходимые низкоуровневые операции сначала выполнит первый поток, а затем — второй, мы получим ожидаемый результат.

Сначала все операции по инкрементированию переменной выполняет первый поток, потом — второй

Но что, если операции, в которые вовлечены регистры, будут выполнены так, что одна из них начнётся до того, как окончится другая? Это приведёт к нарушению синхронизации состояния регистров и оперативной памяти. Например, может случиться так, что один из потоков не примет во внимание результаты вычислений другого и затрёт своими данными то, что он записал в память.

Гонка потоков и операции с регистрами

Избежать подобных ситуаций можно с помощью реализации так называемых «атомарных операций». Суть тут заключается в том, чтобы то, что для программиста выглядит как одна операция, а для компьютера — как несколько, выглядело бы как одна операция и для компьютера.

Атомарные операции позволяют превратить некие действия, которые могут включать в себя множество инструкций процессора, в нечто вроде единой неделимой инструкции. Эта атомарная «инструкция» сохраняет целостность даже если выполнение команд, из которых она состоит, приостанавливается, и, через некоторое время, возобновляется. Атомарные операции иногда сравнивают с атомами.

Набор инструкций, формирующих атомарную операцию

С использованием атомарных операций код для инкрементирования переменной будет выглядеть по-новому. Вместо обычного sharedVar++ это будет нечто вроде Atomics.add(sabView, index, 1). Первый аргумент метода add представляет собой структуру данных для доступа к SharedArrayBuffer (Int8Array, например). Второй — это индекс, по которому sharedVar находится в массиве. Третий аргумент — число, которое нужно прибавить к sharedVar.

Атомарная операция, которая позволяет увеличить переменную на 1

Теперь, когда мы пользуемся методом Atomics.add, действия процессора, связанные с инкрементированием переменной по команде из одного потока, не смешиваются с операциями, инициированными из другого потока. Вместо этого сначала все необходимые действия, в рамках одной атомарной операции, выполняются первым потоком, после чего выполняются операции второго потока, опять же, заключённые в атомарную операцию.

Сначала инструкции, необходимые для инкрементирования переменной, выполняет первый поток, затем — второй

Вот методы Atomics, которые помогают избежать состояния гонок при выполнении отдельных операций.

Можно заметить, что список этот довольно-таки ограниченный. В нём, например, нет методов для выполнения деления или умножения. Однако, разработчики вспомогательных библиотек могут самостоятельно реализовать атомарные методы для выполнения различных операций.

Для реализации подобных вещей можно воспользоваться методом Atomics.compareExchange. С помощью этого метода можно считать некое значение из SharedArrayBuffer, выполнить с ним какие-то действия и записать обратно только в том случае, если оно, во время выполнения действий с ним, не было изменено другим потоком. Если, при попытке записи, оказалось, что значение в SharedArrayBuffer изменилось, запись не выполняется, вместо этого можно взять новое значение и попытаться выполнить ту же операцию снова.

Состояние гонок при выполнении нескольких операций

Атомарные операции, о которых мы говорили выше, позволяют избежать состояния гонок при выполнении одиночных команд. Однако иногда нужно изменить несколько значений в объекте (с использованием нескольких операций) и быть при этом уверенным в том, что никто другой не попытается в то же самое время менять эти значения. В целом, это означает, что, в ходе каждого сеанса обновления состояния объекта, объект должен быть заблокирован и недоступен для других потоков.

Объект Atomics не предоставляет средств, которые позволяют напрямую реализовать подобный функционал, но он даёт инструменты, которые разработчики библиотек могут использовать для создания механизмов, позволяющих выполнять подобные операции. Речь идёт о создании высокоуровневых средств блокировки.

Два потока, общая область памяти и блокировка

Если код хочет использовать общие данные, он должен захватить блокировку. На рисунке выше ни один из потоков не заблокировал общую область памяти, это представлено в виде открытого замка. После захвата поток может использовать блокировку для защиты данных от других потоков. Только он может получить доступ к этим данным или изменить их, пока блокировка активна.

Для того, чтобы создать механизм блокировок, авторы библиотек могут воспользоваться методами Atomics.wait, и Atomics.wake, а так же такими, как Atomics.compareExchange и Atomics.store. Здесь можно взглянуть на базовую реализацию подобного механизма.

При таком подходе, показанном на следующем рисунке, поток №2 захватит блокировку данных и установит значение locked в true. Это означает, что поток №1 не сможет получить доступ к данным до тех пор, пока поток №2 их не разблокирует.

Поток №2 блокирует данные

Если потоку №1 нужен доступ к данным, он попытается захватить блокировку. Но так как блокировка уже используется, сделать он этого не сможет. Поэтому потоку придётся ждать до тех пор, пока данные не окажутся разблокированными.

Поток №1 ожидает снятия блокировки

Как только поток №2 завершит работу, он снимет блокировку. После этого механизм блокировок оповестит ожидающие потоки о том, что они могут захватить блокировку.

Поток №1 получил оповещение о том, что блокировка снята

Теперь поток №1 может захватить блокировку и заблокировать данные для собственного использования.

Поток №1 блокирует данные

Библиотека, реализующая механизм блокировок, могла бы использовать различные методы объекта Atomics, однако, самыми важными из них являются Atomics.wait и Atomics.wake.

Состояние гонок, вызванное изменением порядка выполнения операций

Вот третья проблема синхронизации, в решении которой может помочь объект Atomics. Для кого-то она может оказаться полной неожиданностью.

Возможно, вы этого не знаете, но весьма велики шансы того, что команды программы, написанной вами, не будут выполняться в том порядке, в котором они идут в коде. И компиляторы, и процессор, меняют порядок выполнения кода для того, чтобы более рационально использовать ресурсы компьютера.

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

Фрагмент кода, выполняющего вычисления общей суммы и устанавливающего флаг, сигнализирующий об окончании выполнения операции

Для того, чтобы это скомпилировать, системе надо решить, какой регистр использовать для каждой переменной. После этого JS-код можно перевести в машинные инструкции.

Упрощённый пример преобразования кода на JS в машинные инструкции

Пока всё выглядит так, как и ожидается.

Для тех, кто не очень хорошо разбирается в том, как компьютер работает на аппаратном уровне, как устроены конвейеры, которые используются для выполнения кода, может оказаться не вполне очевидным тот факт, что перед выполнением второй строки нашего кода, машине придётся немного подождать.

Большинство компьютеров разбивает процесс выполнения инструкций на несколько шагов. Это позволяет обеспечить постоянную загрузку всех механизмов процессора, что даёт возможность эффективно пользоваться ресурсами машины.

Вот описание этапов, из которых состоит выполнение инструкции.

Этап №1

Выборка инструкции из памяти

Этап №2

Декодирование инструкции, то есть, выяснение, какие именно действия нужно произвести для выполнения этой инструкции, и загрузка необходимых данных из регистров

Этап №3

Выполнение инструкции

Этап №4

Запись результатов выполнения инструкции в регистры

Вот, очень упрощённо, путь, который проходит по конвейеру первая инструкция. В идеале нам хотелось бы, чтобы выполнение второй инструкции шло сразу за первой. То есть, как только первая инструкция переходит к шагу №2, осуществляется выполнение шага №1 для второй инструкции, и так далее. Проблема заключается в том, что инструкция №2 зависит от инструкции №1.

Инструкции №2 нужно получить значение переменной subTotal из R3, но инструкция №1 ещё не записала туда результат вычислений

В подобной ситуации можно приостановить обработку процессором инструкций до тех пор, пока инструкция №1 не обновит значение переменной subTotal в регистре. Однако, при таком подходе пострадает производительность.

Для того, чтобы использовать ресурсы системы эффективно, множество компиляторов и процессоры меняют порядок выполнения операций. А именно, в нашем случае выполняется поиск инструкций, которые не используют переменные subTotal и total, и выполнение этих инструкций между инструкциями №1 и №2, которые следуют в коде друг за другом.

Изменение порядка выполнения инструкций, инструкция №3 будет выполнена между инструкциями №1 и №2

Это позволяет, в идеале, не прерывать поток инструкций, следующих по конвейеру.

Так как третья строка кода не зависит ни от первой, ни от второй, компилятор или процессор могут решить, что вполне безопасно изменить порядок выполнения инструкций. Когда всё это происходит в однопоточном режиме, внутри функции, другой код не получит доступ к этим значениям до тех пор, пока не завершится выполнение всей функции.

Однако, если имеется ещё один поток, выполняющийся параллельно, всё меняется. Другому потоку не обязательно ждать до тех пор, пока функция завершит работу, для того, чтобы узнать состояние переменных. Эти изменения другой поток может заметить едва ли не сразу же после того, как они произойдут. В результате окажется, что флаг isDone, видимый другому потоку, будет установлен до завершения вычислений. codeisDone как флаг, указывающий на то, что вычисление total завершено, и полученное значение готово к использованию в другом потоке, изменение порядка выполнения операций приведёт к состоянию гонки потоков.

Объект Atomics пытается решать некоторые из подобных странностей. В частности, использование атомарной операции записи напоминает установку забора между двумя фрагментами кода. Отдельные инструкции атомарных операций не смешиваются с другими операциями. В частности, вот две операции, которые часто используются для того, чтобы обеспечить выполнение операций по порядку:

Если обновление некоей переменной выполняется в коде JS-функции выше команды Atomics.store, оно гарантированно будет завершено до того, как Atomics.store сохранит значение переменной в памяти. Если даже порядок выполнения неатомарных инструкций будет изменён по отношению друг к другу, ни одна из них не будет перемещена ниже вызова Atomics.store, размещённого в нижней части кода.

Аналогично, загрузка переменной после вызова Atomics.load гарантированно будет выполнена после того, как Atomics.load прочтёт её значение. Опять же, если даже порядок выполнения неатомарных инструкций будет изменён, ни одна из них не будет перемещена так, что будет выполнена до Atomics.load, которая размещена в коде выше неё.

Обновление переменной выше Atomics.store гарантированно будет выполнено до завершения Atomics.store. Загрузка переменной ниже Atomics.load гарантированно будет выполнена после того, как Atomics.load завершит работу

Обратите внимание на то, что цикл while из этого примера реализует циклическую блокировку, это весьма неэффективная конструкция. Если нечто подобное окажется в главном потоке приложения, программа может попросту зависнуть. В реальном коде, практически наверняка, циклическими блокировками пользоваться не стоит.

Итоги

Многопоточное программирование с разделяемой памятью — задача непростая. Существует множество ситуаций, которые могут вызывать состояние гонки потоков. Они, как драконы, поджидают неопытных разработчиков в самых неожиданных местах.

Многопоточное программирование с разделяемой памятью полно опасностей

Мы, в этой серии из трёх материалов, постоянно говорили о том, что новые средства языка позволяют разработчикам библиотек создать простые, удобные и надёжные инструменты, предназначенные для обычных программистов. Путь SharedArrayBuffer и Atomics во вселенной JavaScript только начинается, поэтому библиотеки, построенные на их основе, пока ещё не созданы. Однако, теперь у JS-сообщества есть всё необходимое для разработки таких библиотек.

Уважаемые читатели! Если вы — из тех высококлассных программистов, не понаслышке знающих о многопоточности, в расчёте на которых созданы SharedArrayBuffer и Atomics, уверены, многим новичкам будет интересно узнать о том, в каком направлении стоит двигаться для того, чтобы стать разработчиком качественных библиотек, реализующих параллельные вычисления. Поделитесь, пожалуйста, опытом.

habr.com

Состояние гонки - Перевод на английский - примеры русский

На основании Вашего запроса эти примеры могут содержать грубую лексику.

На основании Вашего запроса эти примеры могут содержать разговорную лексику.

Раньше при создании или удалении виртуальных сетевых устройств могло возникнуть состояние гонки.

A race condition could occur when creating and destroying virtual network devices.

Состояние гонки - ошибка проектирования или реализации многозадачной системы, при которой работа системы зависит от того, в каком порядке выполняются части кода.

Race condition is an error related to design or implementation of a multitask system when system operation depends upon the order of executing code fragments.

К сожалению, такое распараллеливание некорректно, так как в процессе работы возникнет состояние гонки.

Unfortunately, this way of parallelization is incorrect because a race condition occurs in this code.

Хорошим побочным эффектом этого является избежание риска ошибок при совершении двухфазного rsync (различные фазы могут окончится на разных машинах с некоторым временным окном, когда они имеют различные данные, что вызывает состояние гонки (race condition)).

The upside of doing that is that it avoids the risk of failures when performing a two-stage rsync (different stages might end up on different machines during time windows where they have different data, causing a race condition).

Предложить пример

Другие результаты

В этом выпуске добавлена проверка состояния виртуального устройства с целью предотвращения состояния гонки.

Данный пример содержит ошибку состояния гонки, и возвращаемое ей значение может меняться от запуска к запуску.

This sample contains a race condition and the result it returns may vary from run to run.

Улучшена стабильность работы на платформе Linux за счет исправления состояния гонки при выводе звука.

Improved stability on the Linux platform by fixing a race condition issue in sound output.

В результате переменная value начнет использоваться всеми потоками одновременно, что приведет к ошибке состояния гонки и на выходе мы получим мусор.

As a result, "value" variable will be used by all the threads simultaneously - it will cause a race condition and we will get garbage in the end.

С помощью Parallel Inspector, было выяснено, что в коде возникает несколько ошибок состояния гонки (race condition).

Using Parallel Inspector, we found out that there were several errors of race condition occurring in the code.

Данный пример содержит ошибку состояния гонки (Race condition), и возвращаемое ей значение может меняться от запуска к запуску.

This example contains a race condition error and the value returned by it can vary every time the code is executed.

Существующие международные соглашения не в состоянии предотвратить гонки вооружений в космосе.

Existing international agreements are inadequate to prevent an arms race in outer space.

В-третьих, Куба согласна с мнением о том, что действующий правовой режим не в состоянии предотвратить гонку вооружений в космическом пространстве.

Third, Cuba agreed with the view that the existing legal regime was inadequate to ensure the prevention of an arms race in outer space.

И для того чтобы быть в состоянии положить конец гонке вооружений в различных районах мира, международное сообщество должно сосредоточить усилия на решении именно проблем в сфере обеспечения безопасности на национальном и региональном уровнях.

It is these national and regional security problems which need to be addressed by the international community as a means of halting an arms build-up in various parts of the world.

В силу этого договор, не охватывающий запасов расщепляющегося материала, не только не способствовал бы ядерному разоружению, но и не был бы в состоянии предотвратить новую гонку ядерных вооружений.

For this reason, a treaty that does not cover fissile material stocks not only would not contribute to nuclear disarmament but would also be unable to prevent a new nuclear arms race.

Здесь мы наблюдаем возникновение состояния гонки (гасё condition).

В то же время состояния растрачиваются на оружие, гонку вооружений или предметы роскоши.

At the same time, fortunes are being wasted on armaments, arms races or luxuries.

Вследствие такого парадоксального состояния дел перед нами по-прежнему стоит задача сдерживать гонку вооружений и распространение оружия массового уничтожения.

This paradoxical state of affairs continues to challenge us to contain the arms race and the proliferation of weapons of mass destruction.

Когда этот вопрос был вынесен на рассмотрение, некоторые делегации подчеркивали, что в настоящее время в космосе нет гонки вооружений и что существующий правовой режим в состоянии справиться с возможными будущими событиями.

When the subject was taken up for consideration some delegations pointed out that at present there is no ongoing arms race in outer space and that the existing legal regime is sufficient to take care of any future developments.

Так да благословит sallallaahu Пророка ва саллям дал благую весть в сахих хадис является то, что в этой гонке-прежнему находится в хорошем состоянии.

So the Prophet sallallaahu 'alaihi wa sallam has given the glad tidings in the saheeh hadeeth is that this race continues to be in good condition.

Это была великая гонка, и я считаю потрясающим то, что мы в состоянии провести такие грандиозные мероприятия как сегодня, в американских городах.

It was a great race, and I think it's terrific that we're able to hold huge events like this today in American cities.

context.reverso.net

Состояние гонки — с русского

См. также в других словарях:

  • Состояние гонки — У этого термина существуют и другие значения, см. Гонки. Состояние гонки (англ. race condition)  ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке… …   Википедия

  • Гонки — Гонка соревнование, подразумевающее одновременный старт группы нескольких (двух или более) участников и фиксацию порядка финиша каждого из участников. Особым видом гонок являются матчевые, когда в соревнованиях одновременно участвуют только два… …   Википедия

  • Буря в стакане: Гонки на маршрутках — Разработчики SkyRiver Studios, Божья искра Издатель 1С Создатели Руководитель Валерий Воронин …   Википедия

  • Российская Советская Федеративная Социалистическая Республика, РСФСР (медико-санитарное состояние и здравоохранение) — VII. Медико санитарное состояние и здравоохранение = Здравоохранение. Медицина). В конце 16 в. была организована Аптекарская палата …   Большая советская энциклопедия

  • Поток выполнения — Для термина «Поток» см. другие значения. Процесс с двумя потоками выполнения на одном процессоре Поток выполнения (анг …   Википедия

  • Параллельные вычислительные системы — Не следует путать с Распределённые вычисления. Параллельные вычислительные системы  это физические компьютерные, а также программные системы, реализующие тем или иным способом параллельную обработку данных на многих вычислительных узлах.[1]… …   Википедия

  • Семафор (информатика) — У этого термина существуют и другие значения, см. Семафор. Семафор  объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Эдсгером Дейкстрой. Семафоры используются при передаче данных через разделяемую …   Википедия

  • Мьютекс — (англ. mutex, от mutual exclusion  «взаимное исключение»)  одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихся потоков. Мьютексы  это один из вариантов семафорных механизмов для… …   Википедия

  • Семафор (программирование) — Это статья о методе синхронизации выполняющихся одновременно программ. Остальные значения этого слова описаны в статье Семафор. Семафор объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Э. Дейкстрой.… …   Википедия

  • Взаимная блокировка — двух процессов P1 и P2 нуждающихся в двух ресурсах. Взаимная блокировка (англ. deadlock)  ситуация в многозадачной с …   Википедия

  • Intelligent Platform Management Interface — IPMI (от англ. Intelligent Platform Management Interface)  интеллектуальный интерфейс управления платформой, предназначенный для автономного мониторинга и управления функциями, встроенными непосредственно в аппаратное и микропрограммное …   Википедия

translate.academic.ru

состояние гонки - это... Что такое состояние гонки?

 состояние гонки

General subject: race condition

Универсальный русско-английский словарь. Академик.ру. 2011.

  • состояние гонад
  • состояние горячего резерва

Смотреть что такое "состояние гонки" в других словарях:

  • Состояние гонки — У этого термина существуют и другие значения, см. Гонки. Состояние гонки (англ. race condition)  ошибка проектирования многопоточной системы или приложения, при которой работа системы или приложения зависит от того, в каком порядке… …   Википедия

  • Гонки — Гонка соревнование, подразумевающее одновременный старт группы нескольких (двух или более) участников и фиксацию порядка финиша каждого из участников. Особым видом гонок являются матчевые, когда в соревнованиях одновременно участвуют только два… …   Википедия

  • Буря в стакане: Гонки на маршрутках — Разработчики SkyRiver Studios, Божья искра Издатель 1С Создатели Руководитель Валерий Воронин …   Википедия

  • Российская Советская Федеративная Социалистическая Республика, РСФСР (медико-санитарное состояние и здравоохранение) — VII. Медико санитарное состояние и здравоохранение = Здравоохранение. Медицина). В конце 16 в. была организована Аптекарская палата …   Большая советская энциклопедия

  • Поток выполнения — Для термина «Поток» см. другие значения. Процесс с двумя потоками выполнения на одном процессоре Поток выполнения (анг …   Википедия

  • Параллельные вычислительные системы — Не следует путать с Распределённые вычисления. Параллельные вычислительные системы  это физические компьютерные, а также программные системы, реализующие тем или иным способом параллельную обработку данных на многих вычислительных узлах.[1]… …   Википедия

  • Семафор (информатика) — У этого термина существуют и другие значения, см. Семафор. Семафор  объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Эдсгером Дейкстрой. Семафоры используются при передаче данных через разделяемую …   Википедия

  • Мьютекс — (англ. mutex, от mutual exclusion  «взаимное исключение»)  одноместный семафор, служащий в программировании для синхронизации одновременно выполняющихся потоков. Мьютексы  это один из вариантов семафорных механизмов для… …   Википедия

  • Семафор (программирование) — Это статья о методе синхронизации выполняющихся одновременно программ. Остальные значения этого слова описаны в статье Семафор. Семафор объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Э. Дейкстрой.… …   Википедия

  • Взаимная блокировка — двух процессов P1 и P2 нуждающихся в двух ресурсах. Взаимная блокировка (англ. deadlock)  ситуация в многозадачной с …   Википедия

  • Intelligent Platform Management Interface — IPMI (от англ. Intelligent Platform Management Interface)  интеллектуальный интерфейс управления платформой, предназначенный для автономного мониторинга и управления функциями, встроенными непосредственно в аппаратное и микропрограммное …   Википедия

universal_ru_en.academic.ru

Как я взломал Starbucks для безлимитного кофе / Хабр

Это история о том, как я нашел способ нагенерить неограниченное число денег на подарочные карты старбакса, тем самым обеспечить себе пожизненный бесплатный кофе, ну или украсть у них пару миллионов другими способами.

Итак, не так давно мне в голову пришла идея купить 3 карты Старбакса по $5 каждая.

На сайте starbucks.com есть личный кабинет, где можно добавить эти карты, смотреть баланс и даже переводить деньги между картами.

Есть такой малоизвестный класс уязвимостей «race condition». Могу с уверенностью заявить, что большинство приложений, которые могут быть уязвимы, к этой атаке скорее всего уязвимы, ведь далеко не каждый программист при проектировке программ учитывает такие факторы, как параллельность выполнения кода и его последствия.

В веб-приложениях он тоже встречается, обычно в функциях связанных с переводом денег/очков/фантиков/ваучеров. Обо всех тонкостях эксплуатации я расскажу в другой раз, а пока вернемся к переводу между картами в Старбаксе.

Перевод строился из нескольких stateful запросов. Схематично — первый запрос POST /step1?amount=1&from=wallet1&to=wallet2 закладывал все эти значения в сессию на сервере, и лишь второй POST/step2?confirm переводил данные уже заложенные в сессии и очищал ее.

Это существенно усложняет эксплуатацию относительно классической гонки, где нужно лишь повторить один и тот же запрос несколько раз одновременно. Ведь как только первый запрос очищает сессию, второй уже натыкается на пустую сессию! И чтобы как-то заставить это работать, пришлось бы делать сложную композицию запросов, записывающую в сессию сразу после ее очищения первым запросом и перед выполнением второго запроса. Такое могло бы сработать раз из миллиона попыток, или вообще не сработать.

Но всегда есть обход для таких «полу защит» — можно залогиниться в один и тот же аккаунт с двух разных браузеров / сессий. Тогда эксплуатация выглядит приблизительно так:

#закладываем параметры перевода в обе сессии curl starbucks/step1 -H «Cookie: session=session1» --data «amount=1&from=wallet1&to=wallet2» curl starbucks/step1 -H «Cookie: session=session2» --data «amount=1&from=wallet1&to=wallet2» #одновременное одобрение перевода $1 с карты 1 на карту 2. curl starbucks/step2?confirm -H «Cookie: session=session1» & curl starbucks/step2?confirm -H «Cookie: session=session2» &

После 5 попыток ничего интересного не произошло и я хотел уже было сдаться. Особенность состояния гонки в том, что ее можно лишь попытаться найти стороннему атакующему, ведь неизвестно, какие защиты стоят (число запросов по IP? запросов на аккаунт? запросов на действие?) и единственный способ проверить уязвимы ли вы — это тщательно проаудировать исходный код на наличие должных пессимистических локов в базе данных.

На 6-ой запрос произошло чудо — перевод был произведен два раза и у меня стало две карты с 15 и 5 долларами, 20 в сумме. Чтобы считать это за proof of concept, осталось убедиться, что магазин примет эти карты.

Я пошел в ближайший работающий Cтарбакс на market st.

— Дайте мне чего-нибудь на $16. — O_o. — Ну что у вас самое дорогое? — Вон те сэндвичи.

Вышло $16.70.

Итак, в нашу маленькую операцию Ы было инвестировано 15 долларов, а закупок сделано на 16.70. Зная отношение самого гуманного суда США к хакерам, я вернувшись домой, сразу зачислил еще $10 с кредитки на карту Старбакса, чтобы не быть должным корпорации целых $1.70, мало ли.

Дальше самое сложное — процесс репорта. Саппорт честно ответил, что не может связать меня с технической командой, ну вообще никак, и им очень жаль, что я feel this way. Написал на [email protected] 23 марта, тишина (ответили, кстати, аж 29 апреля). Пришлось через знакомых знакомых находить людей, которым не все равно и лишь через 10 дней уязвимость была исправлена.

Спасибо никто не сказал, зато был сделан не двусмысленный намек, что я совершил «fraud» и «malicious actions» и что они еще подумают, что со мной сделать.

А что мог сделать я? Я мог запустить ферму из фейковых гифт-карт, купленных в разных магазинах мира, нагенерить на них кучу денег и продавать на специальных промо сайтах с 50 процентной скидкой (чтобы не вызывать подозрения) за биткоины. Так, проработав год-другой, можно было бы высосать пару миллионов долларов из этой дружелюбной фирмы со сладким кофе.

habr.com


   

           ПроАвтоСпорт | Все права защищены © 2018 | Карта сайта