Поиск по сайту:

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


Вы когда-нибудь участвовали в гонках? Если да, то вы уже знаете, что иногда для выбора победителя требуется фотофиниш! А что, если к финишу одновременно прибудут два человека? Добро пожаловать в условия гонки.

Что такое компьютерные потоки?

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

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

В Linux такой поток однозначно идентифицируется с помощью PID (идентификатора процесса). Чтобы узнать больше о PID в Linux, вы можете прочитать наши статьи Основы автоматизации и сценариев Bash (часть 3) и Как работают сигналы Linux: SIGINT, SIGTERM и SIGKILL.

В Windows поток также однозначно идентифицируется идентификатором процесса (см. столбец PID в диспетчере задач Windows), хотя реализация обработки процессов в Linux и Windows отличается; другой базовый код, разные инструменты взаимодействия PID и т. д., а также ограниченная совместимость. Кроме того, идентификатор процесса Windows PID не следует путать с идентификатором продукта PID (тот же термин, но другое значение) или VID (идентификатор поставщика). Последние два относятся к идентификации устройств и не связаны с управлением процессами.

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

Вы также можете думать о нитях, как о бегунах в гонке. Например, представьте загруженный сервер базы данных, обслуживающий множество различных подключенных клиентов. Каждый из этих клиентских потоков (обратите внимание на использование слова «поток») будет (во многих случаях) сам по себе иметь по крайней мере один поток на хост-сервере базы данных и/или внутри самого программного обеспечения базы данных (т. е. два потока, один зарегистрированный). в операционную систему и один в программное обеспечение базы данных).

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

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

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

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

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

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

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

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

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

Предотвращение состояний гонки: безопасность потоков

Было много дискуссий по поводу условий гонки в ИТ-индустрии. В зависимости от используемого вами языка кодирования может быть много или мало возможностей для обработки условий гонки. Часто используется термин потокобезопасность или потокобезопасность приложения или языка программирования [construct]. Такие термины используются для обозначения того, является ли часть кода или программного обеспечения в целом поточно-ориентированным, т. е. написана ли она таким образом, чтобы избежать и даже предотвратить условия гонки.

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

Различные конструкции программирования могут использоваться для предотвращения условий гонки. Например, семафоры и мьютексы. Сложность использования таких конструкций будет зависеть от используемого языка программирования и их встроенной поддержки улучшенной обработки потоков. Например, в C++ можно посмотреть на класс std::mutex для реализации блокировки мьютекса (т. е. взаимоисключающего). Однако в Bash такой конструкции изначально нет.

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

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

Подведение итогов

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

Если вам понравилась эта статья, посмотрите статью «Как работают логические вентили: ИЛИ, И, исключающее ИЛИ, ИЛИ, НЕ-И, исключающее ИЛИ и НЕ».