4 General principles [intro]

4.7 Multi-threaded executions and data races [intro.multithread]

4.7.2 Forward progress [intro.progress]

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

  • прекратить,

  • выполнить вызов функции ввода-вывода библиотеки,

  • выполнить доступ через изменчивое значение glvalue, или

  • выполнить операцию синхронизации или атомарную операцию.

[ Note: Это сделано для того, чтобы позволить преобразования компилятора, такие как удаление пустых циклов, даже если завершение не может быть доказано. ] end note

Выполнение элементарных функций, которые либо определены как есть, lock-free либо указаны как lock-free есть lock-free executions.

  • Если есть только один поток, которого нет blocked в стандартной библиотечной функции, выполнение в этом потоке без блокировки должно завершиться. [ Note: Одновременное выполнение потоков может помешать продвижению безблокирующего выполнения. Например, такая ситуация может возникнуть с реализациями условного хранилища с блокировкой загрузки. Это свойство иногда называют свободным от препятствий. ] end note

  • Когда одно или несколько запусков без блокировки выполняются одновременно, по крайней мере одно должно завершиться. [ Note: Для некоторых реализаций трудно обеспечить абсолютные гарантии этого эффекта, поскольку повторяющиеся и, в частности, неподходящие помехи со стороны других потоков могут препятствовать продвижению вперед, например, путем многократного перехвата строки кэша для несвязанных целей между инструкциями с блокировкой загрузки и условными сохранениями. Реализации должны гарантировать, что такие эффекты не могут на неопределенное время задерживать прогресс в ожидаемых рабочих условиях, и что такие аномалии, следовательно, могут безопасно игнорироваться программистами. Вне этого документа это свойство иногда называют свободным от блокировки. ] end note

Во время выполнения потока выполнения каждое из следующего называется execution step:

  • завершение потока исполнения,

  • выполнение доступа через изменчивое значение glvalue, или

  • завершение вызова функции ввода-вывода библиотеки, операции синхронизации или атомарной операции.

Вызов стандартной библиотечной функции, которая, blocks как считается, непрерывно выполняет шаги выполнения, ожидая выполнения условия, которое она блокирует. [ Example: Библиотечная функция ввода-вывода, которая блокируется до завершения операции ввода-вывода, может рассматриваться для непрерывной проверки того, завершена ли операция. Каждая такая проверка может состоять из одного или нескольких этапов выполнения, например, с использованием наблюдаемого поведения абстрактной машины. ]end example

[ Note: Из-за этого и предыдущего требования относительно того, какие потоки выполнения должны выполняться в конечном итоге, отсюда следует, что ни один поток выполнения не может выполняться вечно без выполнения шага выполнения. ]end note

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

Для потока выполнения concurrent forward progress guaranteesреализация гарантирует, что поток в конечном итоге будет прогрессировать до тех пор, пока он не завершится. [ Note: Это требуется независимо от того, выполнялись или нет другие потоки выполнения (если есть). В конечном итоге выполнение этого требования означает, что это произойдет в неопределенный, но конечный период времени. ]end note

Это определяется реализацией, обеспечивают ли созданные реализациейmain потоки выполнения, которые выполняются, и потоки выполнения, созданные с помощью std​::​thread параллельных гарантий продвижения вперед. [ Note: Рекомендуется, чтобы реализации общего назначения предоставляли эти гарантии. ]end note

Для потока выполнения parallel forward progress guaranteesреализация не требуется, чтобы гарантировать, что поток в конечном итоге будет прогрессировать, если он еще не выполнил ни одного шага выполнения; после того, как этот поток выполнил шаг, он предоставляет гарантии одновременного продвижения вперед.

[ Note: Здесь не указывается требование о том, когда запускать этот поток выполнения, которое обычно указывается сущностью, создающей этот поток выполнения. Например, поток выполнения, который обеспечивает одновременные гарантии продвижения вперед и выполняет задачи из набора задач в произвольном порядке, одну за другой, удовлетворяет требованиям параллельного продвижения вперед для этих задач. ]end note

Для потока выполнения weakly parallel forward progress guaranteesреализация не гарантирует, что поток в конечном итоге будет прогрессировать.

[ Note: Нельзя ожидать, что потоки выполнения, обеспечивающие слабо параллельные гарантии продвижения вперед, будут прогрессировать, независимо от того, работают ли другие потоки или нет; однако блокировка с делегированием гарантии продвижения вперед, как определено ниже, может использоваться для обеспечения того, чтобы такие потоки выполнения в конечном итоге достигли прогресса. ]end note

Гарантии одновременного продвижения вперед сильнее, чем гарантии параллельного продвижения вперед, которые, в свою очередь, сильнее, чем гарантии слабо параллельного продвижения вперед. [ Note: Например, некоторые виды синхронизации между потоками выполнения могут выполняться только в том случае, если соответствующие потоки выполнения обеспечивают параллельные гарантии продвижения вперед, но не смогут достичь прогресса при слабо параллельных гарантиях. ]end note

Когда поток выполнения P указывается для block with forward progress guarantee delegation завершения набора S потоков выполнения, то в течение всего времени P блокировки Sреализация должна гарантировать, что гарантии продвижения вперед, предоставляемые по крайней мере одним потоком выполнения в S , по крайней мере столь же сильны, как Pи гарантии продвижения вперед. [ Note: Не указано, какой поток или потоки выполнения S выбраны и для какого количества шагов выполнения. Усиление не является постоянным и не обязательно действует до конца жизненного цикла затронутого потока выполнения. Пока P он заблокирован, реализация должна в конечном итоге выбрать и потенциально усилить поток выполнения в S. ] Как только поток выполнения в in завершается, он удаляется из . Когда-то пусто, разблокировано.end note S S S P

[ Таким образом, Note: поток выполнения B может временно обеспечить более надежную гарантию продвижения вперед на определенное время из-за того, что второй поток выполнения A блокируется на нем с делегированием гарантии продвижения вперед. В свою очередь, если B затем блоки с включенной гарантией продвижения вперед C, это также может временно обеспечить более сильную гарантию продвижения вперед C. ]end note

[ Note: Если все потоки выполнения находятся на стадии S завершения (например, они завершаются и не используют блокирующую синхронизацию неправильно), то Pвыполнение операции, которая блокируется с делегированием гарантии выполнения вперед, не приведет Pк эффективному ослаблению гарантии выполнения. ]end note

[ Note: Это не снимает каких-либо ограничений, касающихся блокировки синхронизации для потоков выполнения, обеспечивая параллельные или слабо параллельные гарантии продвижения вперед, потому что реализация не требуется для усиления конкретного потока выполнения, слишком слабая гарантия выполнения которого препятствует общему прогрессу. ]end note

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