Состояние гонки
Состоя́ние го́нки (англ. race condition) в параллельных вычислениях, в широком смысле – любая ситуация, которая возникает, если поведение вычислительной системы зависит от порядка выполнения кода в различных параллельных активностях (программных сущностях). Таковой является, например, ситуация, при которой возможно одновременное чтение некоторой переменной в одном потоке и запись в эту же переменную в другом потоке. В этом случае в зависимости от порядка следования инструкций дальнейшее выполнение возможно с различными значениями этой разделяемой переменной. Здесь и далее будет использован термин «поток» для обозначения параллельной активности, тем не менее всё дальнейшее верно и для других активностей (например, процессов).
Состояние гонки само по себе не является ошибкой, однако очень часто приводит к другим ошибкам (т. е. нарушению свойств безопасности), таким как разыменование нулевого указателя, выход за границу массива и др.
Для защиты от состояния гонки часто применяются различные примитивы синхронизации, которые обеспечивают защиту от одновременного исполнения в нескольких потоках некоторого участка кода.
Более известно следующее определение, сформулированное Л. Лэмпортом: состояние гонки возникает, если несколько параллельных активностей (например, потоков) получают одновременный доступ к области памяти, при этом один из доступов является записью. Оно определяет более узкий класс ошибок – состояние гонки по данным (англ. data race). Высокоуровневой гонкой называют ситуацию, при которой параллельный доступ происходит к разным, но при этом зависимым областям памяти. Также следует упомянуть безобидные состояния гонки, например одновременное увеличение счётчика статистики.
Состояние гонки характеризуется теми же особенностями, что и другие ошибки, связанные с параллельным исполнением кода. Оно имеет случайный характер, т. к. для его возникновения необходимо воспроизвести определённую последовательность действий в нескольких параллельных потоках. Состояние гонки достаточно сложно обнаружить и локализовать в первую очередь из-за случайного характера таких ошибок. Именно поэтому, помимо традиционного тестирования для проверки сложных программных систем, применяются различные техники как динамического, так и статического анализа. Ошибки, связанные с состоянием гонки, часто непросто исправить, т. к. не всегда проблема решается использованием примитивов синхронизации.
См. также Взаимная блокировка.