Фьючерсы и обещания
В информатике , будущее синхронизации обещание , задержка и отложенное относятся к конструкциям, используемым для выполнения в программы некоторых параллельных языках программирования . Они описывают объект, который действует как прокси для результата, который изначально неизвестен, обычно потому, что вычисление его значения еще не завершено.
Термин «обещание» был предложен в 1976 году Дэниелом П. Фридманом и Дэвидом Уайзом. [1] и Питер Хиббард назвал это возможным . [2] Несколько похожая концепция будущего была представлена в 1977 году в статье Генри Бейкера и Карла Хьюитта . [3]
Термины будущее , обещание , задержка и отсрочка часто используются как взаимозаменяемые, хотя некоторые различия в использовании между будущим и обещанием рассматриваются ниже. В частности, если различать использование, будущее представляет собой представление переменной, доступное только для чтения , а обещание — это записываемый контейнер с одним назначением , который устанавливает значение будущего. Примечательно, что будущее может быть определено без указания того, какое конкретное обещание будет устанавливать его значение, а различные возможные обещания могут устанавливать значение данного будущего, хотя это можно сделать только один раз для данного будущего. В других случаях будущее и обещание создаются вместе и связываются друг с другом: будущее — это значение, обещание — это функция, которая устанавливает значение — по сути, возвращаемое значение (будущее) асинхронной функции (промиса). Установка значения будущего также называется его разрешением , выполнением или связыванием .
Приложения [ править ]
Фьючерсы и обещания возникли в функциональном программировании и связанных с ним парадигмах (таких как логическое программирование ) для отделения значения (будущего) от того, как оно было вычислено (обещание), что позволяет выполнять вычисления более гибко, в частности, путем их распараллеливания. Позже он нашел применение в распределенных вычислениях , для уменьшения задержки при передаче туда и обратно. Еще позже он получил более широкое применение, позволив писать асинхронные программы в прямом стиле , а не в стиле передачи продолжения .
Неявный против. явно [ править ]
Использование фьючерсов может быть неявным (любое использование фьючерса автоматически получает его значение, как если бы это была обычная ссылка ) или явным (пользователь должен вызвать функцию для получения значения, например get
метод java.util.concurrent.Future
на Яве ). Получение ценности явного будущего можно назвать уколом или принуждением . Явные фьючерсы могут быть реализованы в виде библиотеки, тогда как неявные фьючерсы обычно реализуются как часть языка.
В оригинальной статье Бейкера и Хьюитта описывались неявные фьючерсы, которые естественным образом поддерживаются в актерской модели вычислений и в чисто объектно-ориентированных языках программирования, таких как Smalltalk . В статье Фридмана и Уайза описываются только явные фьючерсы, что, вероятно, отражает сложность эффективной реализации неявных фьючерсов на стандартном оборудовании. Трудность заключается в том, что стандартное оборудование не поддерживает фьючерсы для примитивных типов данных, таких как целые числа. Например, инструкция добавления не знает, как обращаться с 3 + future factorial(100000)
. В чистых актерских или объектных языках эту проблему можно решить, отправив future factorial(100000)
сообщение +[3]
, который просит будущее добавить 3
самому себе и вернуть результат. Обратите внимание, что метод передачи сообщений работает независимо от того, когда factorial(100000)
завершает вычисление и что никакое воздействие/принуждение не требуется.
Конвейеризация обещаний [ править ]
Использование фьючерсов может значительно снизить задержку в распределенных системах . Например, фьючерсы позволяют конвейеризировать обещания , [4] [5] как реализовано в языках E и Joule , что также называлось call-stream [6] на языке Аргус .
Рассмотрим выражение, включающее обычные вызовы удаленных процедур , например:
t3 := ( x.a() ).c( y.b() )
который можно было бы расширить до
t1 := x.a(); t2 := y.b(); t3 := t1.c(t2);
Перед выполнением следующего запроса каждому оператору необходимо отправить сообщение и получить ответ. Предположим, например, что x
, y
, t1
, и t2
все они расположены на одной и той же удаленной машине. В этом случае должны произойти два полных сетевых обращения к этой машине, прежде чем третий оператор сможет начать выполняться. Третий оператор затем вызовет еще один возврат к той же удаленной машине.
Используя фьючерсы, приведенное выше выражение можно записать
t3 := (x <- a()) <- c(y <- b())
который можно было бы расширить до
t1 := x <- a(); t2 := y <- b(); t3 := t1 <- c(t2);
Здесь используется синтаксис языка E, где x <- a()
значит отправить сообщение a()
асинхронно с x
. Всем трем переменным немедленно присваиваются фьючерсы на их результаты, и выполнение переходит к последующим операторам. Более поздние попытки определить ценность t3
может вызвать задержку; однако конвейеризация может сократить количество необходимых обращений туда и обратно. Если, как в предыдущем примере, x
, y
, t1
, и t2
все расположены на одной и той же удаленной машине, конвейерная реализация может вычислить t3
с одним рейсом туда и обратно вместо трех. Поскольку все три сообщения предназначены для объектов, находящихся на одном и том же удаленном компьютере, необходимо отправить только один запрос и получить только один ответ, содержащий результат. Отправка t1 <- c(t2)
не заблокировал бы, даже если t1
и t2
находились на разных машинах друг от друга или x
или y
.
Конвейерную обработку обещаний следует отличать от параллельной асинхронной передачи сообщений. В системе, поддерживающей параллельную передачу сообщений, но не конвейерную обработку, сообщение отправляется x <- a()
и y <- b()
в приведенном выше примере может происходить параллельно, но отправка t1 <- c(t2)
придется подождать, пока оба t1
и t2
было получено, даже когда x
, y
, t1
, и t2
находятся на одной удаленной машине. Преимущество конвейерной обработки в относительной задержке становится еще больше в более сложных ситуациях, включающих большое количество сообщений.
Конвейерную обработку обещаний также не следует путать с конвейерной обработкой сообщений в системах актеров, где актер может указать и начать выполнение поведения для следующего сообщения до завершения обработки текущего сообщения.
Просмотры только для чтения [ править ]
В некоторых языках программирования, таких как Oz , E и AmbientTalk , можно получить доступное только для чтения представление будущего, которое позволяет читать его значение при разрешении, но не позволяет его разрешить:
- В стране Оз
!!
Оператор используется для получения представления, доступного только для чтения. - В E и AmbientTalk будущее представлено парой значений, называемой парой обещание/резольвер . Промис представляет собой представление, доступное только для чтения, а преобразователь необходим для установки будущего значения.
- В С++ 11а
std::future
обеспечивает просмотр только для чтения. Значение задается непосредственно с помощьюstd::promise
или установить результат вызова функции, используяstd::packaged_task
илиstd::async
. - В Deferred API Dojo Toolkit начиная с версии 1.5 объект обещания, предназначенный только для потребителя, представляет собой представление, доступное только для чтения. [7]
- В Alice ML фьючерсы предоставляют представление только для чтения , тогда как обещание содержит как будущее, так и возможность разрешить будущее. [8] [9]
- В .NET
System.Threading.Tasks.Task<T>
представляет представление только для чтения. Разрешение значения может быть выполнено с помощьюSystem.Threading.Tasks.TaskCompletionSource<T>
.
Поддержка представлений только для чтения соответствует принципу наименьших привилегий , поскольку позволяет устанавливать значение только для субъектов , которым необходимо его установить. В системе, которая также поддерживает конвейерную обработку, отправитель асинхронного сообщения (с результатом) получает обещание результата только для чтения, а цель сообщения получает преобразователь.
Специфические фьючерсы [ править ]
Некоторые языки, такие как Alice ML , определяют фьючерсы, связанные с определенным потоком, который вычисляет значение фьючерса. [9] Эти вычисления могут начинаться либо сразу , когда создается будущее, либо лениво , когда его значение впервые требуется. Ленивое будущее похоже на thunk в смысле отложенного вычисления.
Алиса ML также поддерживает фьючерсы, которые могут быть разрешены любым потоком, и называет эти обещания . [8] Такое использование обещания отличается от его использования в E, как описано выше . В Алисе обещание не доступно только для чтения, а конвейеризация обещаний не поддерживается. Вместо этого конвейеризация естественным образом происходит для фьючерсов, в том числе связанных с обещаниями.
Блокирующая и неблокирующая семантика [ править ]
Если доступ к значению будущего осуществляется асинхронно, например, путем отправки ему сообщения или явного ожидания его с помощью такой конструкции, как when
в E, тогда нет никаких трудностей с отсрочкой до тех пор, пока будущее не будет решено, прежде чем сообщение будет получено или ожидание завершится. Это единственный случай, который следует учитывать в чисто асинхронных системах, таких как чистые языки актеров.
Однако в некоторых системах также можно попытаться немедленно или синхронно получить доступ к значению будущего времени. Далее предстоит сделать выбор дизайна:
- доступ может заблокировать текущий поток или процесс до тех пор, пока не будет решено будущее (возможно, с тайм-аутом). Это семантика переменных потока данных в языке Oz .
- попытка синхронного доступа всегда может сигнализировать об ошибке, например, о выдаче исключения . Такова семантика удаленных обещаний у Э. [10]
- потенциально доступ может быть успешным, если будущее уже решено, но сигнализировать об ошибке, если это не так. Недостаток этого подхода заключается в введении недетерминированности и возможности возникновения гонок , и это, по-видимому, необычный выбор при проектировании.
В качестве примера первой возможности в C++11 поток, которому нужно значение будущего, может блокироваться до тех пор, пока оно не станет доступным, вызвав метод wait()
или get()
функции-члены. Вы также можете указать тайм-аут ожидания, используя wait_for()
или wait_until()
функции-члены, чтобы избежать неопределенной блокировки. Если бы будущее возникло из-за призыва к std::async
тогда блокирующее ожидание (без таймаута) может привести к синхронному вызову функции для вычисления результата в ожидающем потоке.
Связанные конструкции [ править ]
Фьючерсы — это частный случай примитива синхронизации « событий », который может быть завершен только один раз. В общем, события можно сбрасывать в исходное пустое состояние и, таким образом, выполнять сколько угодно раз. [11]
I -var (как и в языке Id ) — это будущее с семантикой блокировки, как определено выше. I -структура — это структура данных, содержащая I-переменные. Связанная конструкция синхронизации, которую можно устанавливать несколько раз с разными значениями, называется M-var . M-переменные поддерживают атомарные операции по получению или помещению текущего значения, при этом принятие значения также возвращает M-var в исходное пустое состояние. [12]
Параллельная логическая переменная [ нужна ссылка ] похож на будущее, но обновляется унификацией , так же, как логические переменные в логическом программировании . Таким образом, его можно привязать к унифицированным значениям более одного раза, но нельзя вернуть в пустое или неразрешенное состояние. Переменные потока данных Oz действуют как переменные параллельной логики, а также имеют семантику блокировки, как упоминалось выше.
Переменная параллельного ограничения — это обобщение переменных параллельной логики для поддержки программирования логики ограничений : ограничение можно сужать несколько раз, указывая меньшие наборы возможных значений. Обычно существует способ указать преобразователь, который должен запускаться всякий раз, когда ограничение еще больше сужается; это необходимо для поддержки распространения ограничений .
Отношения между выраженностью разных форм будущего [ править ]
Eager фьючерсы, специфичные для потока, можно напрямую реализовать в фьючерсах, не специфичных для потока, путем создания потока для вычисления значения одновременно с созданием будущего. В этом случае желательно вернуть клиенту представление только для чтения, чтобы только вновь созданный поток мог разрешить это будущее.
Для реализации неявных ленивых фьючерсов, специфичных для потока (как, например, предоставлено Алисой ML) в терминах фьючерсов, не специфичных для потока, необходим механизм, определяющий, когда значение фьючерса требуется в первую очередь (например, WaitNeeded
построить в стране Оз [13] ). Если все значения являются объектами, то достаточно возможности реализовать прозрачные объекты пересылки, поскольку первое сообщение, отправленное в пересылку, указывает на то, что требуется будущее значение.
Неспецифические для потока фьючерсы могут быть реализованы в фьючерсах, специфичных для потока, при условии, что система поддерживает передачу сообщений, заставляя разрешающий поток отправлять сообщение в собственный поток будущего. Однако это можно рассматривать как ненужную сложность. В языках программирования, основанных на потоках, наиболее выразительным подходом, по-видимому, является обеспечение сочетания фьючерсов, не связанных с потоками, представлений только для чтения и либо конструкции WaitNeeded , либо поддержки прозрачной пересылки.
Стратегия оценки [ править ]
Стратегия оценки фьючерсов, которую можно назвать вызовом будущего , недетерминирована: ценность фьючерса будет оцениваться в какой-то момент между созданием фьючерса и моментом использования его значения, но точное время не определяется. заранее и может меняться от запуска к запуску. Вычисление может начаться сразу после создания будущего ( активная оценка ) или только тогда, когда значение действительно необходимо ( ленивая оценка ), и может быть приостановлено на полпути или выполнено за один прогон. Как только значение будущего присвоено, оно не пересчитывается при будущих обращениях; это похоже на мемоизацию, используемую при вызове по необходимости .
А ленивое будущее — это будущее, которое детерминированно имеет семантику ленивых вычислений: вычисление значения будущего начинается, когда это значение впервые необходимо, как при вызове по необходимости. Ленивые будущие значения используются в языках, стратегия оценки которых по умолчанию не является ленивой. Например, в C++11 такие ленивые фьючерсы можно создать, передав std::launch::deferred
начать политику std::async
, а также функцию для вычисления значения.
Семантика будущего в модели актора [ править ]
В модели актера выражение вида future <Expression>
определяется тем, как он реагирует на Eval
сообщение со средой E и клиентом C следующим образом: Выражение будущего отвечает на Eval
сообщение, отправив клиенту C вновь созданный актер F (прокси для ответа на оценку <Expression>
) в качестве возвращаемого значения одновременно с отправкой <Expression>
а Eval
сообщение со средой E и C. клиентом Поведение F по умолчанию следующее:
- Когда F получает запрос R , он проверяет, получил ли он уже ответ (который может быть либо возвращаемым значением, либо выброшенным исключением) от оценки
<Expression>
действуя следующим образом:- Если у него уже есть ответ V , то
- Если V возвращаемое значение, то отправляется запрос R. —
- Если V оно выбрасывается заказчику запроса R. является исключением, то
- Если ответа еще нет, то R сохраняется в очереди запросов F. внутри
- Если у него уже есть ответ V , то
- Когда F получает ответ V от оценки
<Expression>
, то V сохраняется в F и- Если V возвращаемое значение, то все запросы в очереди отправляются в V. —
- Если V является исключением, то оно выдается клиенту каждого из запросов в очереди.
Однако некоторые фьючерсы могут обрабатывать запросы особым образом, чтобы обеспечить больший параллелизм. Например, выражение 1 + future factorial(n)
может создать новое будущее, которое будет вести себя как число 1+factorial(n)
. Этот трюк не всегда срабатывает. Например, следующее условное выражение:
if m>future factorial(n) then print("bigger") else print("smaller")
приостанавливает до будущего для factorial(n)
ответил на запрос, спрашивающий, если m
больше, чем он сам.
История [ править ]
Конструкции будущего были впервые реализованы в таких языках программирования , и/или обещания как MultiLisp и Act 1 . Использование логических переменных для связи в параллельной языках программирования логики очень похоже на фьючерсы. Они начались в Прологе с Freeze и IC Prolog и стали настоящим примитивом параллелизма с Relational Language, Concurrent Prolog , защищенными предложениями Horn (GHC), Parlog , Strand , Vulcan , Janus , Oz-Mozart , Flow Java и Alice ML . с одним присвоением I-var из программирования потоков данных языков , происходящий из Id Reppy и включенный в Concurrent ML , во многом похож на переменную параллельной логики.
Техника конвейеризации обещаний (использование фьючерсов для преодоления задержек) была изобретена Барбарой Лисков и Любой Шрирой в 1988 году. [6] и независимо Марком С. Миллером , Дином Трибблом и Робом Джеллингхаусом в контексте проекта «Занаду» около 1989 года. [14]
Термин обещание был придуман Лисковым и Шрирой, хотя они ссылались на механизм конвейерной обработки под названием call-stream , которое сейчас используется редко.
Как дизайн, описанный в статье Лискова и Шриры, так и реализация конвейерной обработки обещаний в Xanadu, имели ограничение, заключающееся в том, что значения обещаний не были первоклассными : аргумент или значение, возвращаемое вызовом или отправкой, не могли напрямую быть обещанием. (поэтому приведенный ранее пример конвейерной обработки обещаний, в котором обещание для результата одной отправки используется в качестве аргумента для другой, не мог быть напрямую выражен в конструкции потока вызовов или в реализации Xanadu). Похоже, что обещания и потоки вызовов никогда не были реализованы ни в одной публичной версии Argus. [15] язык программирования, использованный в статье Лискова и Шриры. Разработка Argus остановилась примерно в 1988 году. [16] Реализация конвейерной обработки обещаний в Xanadu стала общедоступной только после выпуска исходного кода Udanax Gold. [17] в 1999 году и никогда не объяснялся ни в одном опубликованном документе. [18] Более поздние реализации в Joule и E полностью поддерживают первоклассные промисы и преобразователи.
Несколько ранних актерских языков, включая серию Act, [19] [20] поддерживал как параллельную передачу сообщений, так и конвейерную обработку сообщений, но не обещал конвейерную обработку. (Хотя технически возможно реализовать последнюю из этих функций в первых двух, нет никаких доказательств того, что языки Закона сделали это.)
После 2000 года произошло значительное возрождение интереса к фьючерсам и обещаниям из-за их использования в отзывчивости пользовательских интерфейсов, а также в веб-разработке из-за запрос-ответ» модели передачи сообщений « . В нескольких основных языках теперь есть языковая поддержка фьючерсов и обещаний, наиболее популяризированная FutureTask
в Java 5 (анонсировано в 2004 г.) [21] и конструкции async/await в .NET 4.5 (анонсировано в 2010 г., выпущено в 2012 г.) [22] [23] во многом вдохновлен асинхронными рабочими процессами F#, [24] который датируется 2007 годом. [25] Впоследствии это было принято другими языками, в частности Dart (2014), [26] Питон (2015), [27] Hack (HHVM) и черновики ECMAScript 7 (JavaScript), Scala и C++ (2011 г.).
Список реализаций [ править ]
Некоторые языки программирования поддерживают фьючерсы, обещания, переменные параллельной логики, переменные потока данных или I-вары либо посредством прямой языковой поддержки, либо в стандартной библиотеке.
[ править ]
- АБКЛ/ф [28]
- Элис МЛ
- AmbientTalk (включая первоклассные преобразователи и обещания только для чтения)
- C++ , начиная с C++11 : std::future и std::promise.
- Композиционный C++
- Кристалл (язык программирования)
- Дарт (с Future / Completer классами [29] и ключевые слова await и async [26] )
- Elm (язык программирования) через Task модуль [30]
- Глазго Haskell (только I-вары и M-вары)
- Идентификатор (только I-вары и M-вары)
- Этот [31]
- Java через
java.util.concurrent.Future
илиjava.util.concurrent.CompletableFuture
- JavaScript согласно ECMAScript 2015, [32] и через ключевые слова
async
иawait
начиная с ECMAScript 2017 [33] - Lucid (только поток данных)
- Некоторые Липсы
- .NET через Task s
- Котлин , однако
kotlin.native.concurrent.Future
обычно используется только при написании Kotlin, предназначенного для запуска в исходном виде. [35] - Nim
- Кислород
- Оз версия 3 [36]
- Python concurrent.futures , начиная с версии 3.2, [37] как предложено PEP 3148 , а в Python 3.5 добавлены асинхронность и ожидание [38]
- R (обещания для ленивых вычислений, все еще однопоточные)
- Ракетка [39]
- Раку [40]
- Ржавчина (обычно достигается с помощью
.await
) [41] - Scala через пакет scala.concurrent
- Схема
- Писк
- Стрэнд
- Swift (только через сторонние библиотеки)
- Визуальный Бейсик [ нужны разъяснения ] 11 (через ключевые слова Async и Await ) [23]
Языки, также поддерживающие конвейеризацию обещаний, включают:
Список реализаций фьючерсов на основе библиотек [ править ]
- Для Common Lisp :
- Для С++:
- Для C# и других языков .NET : параллельных расширений. библиотека
- Для Groovy : GPars [54]
- Для JavaScript :
- Cujo.js' [55] когда.js [56] предоставляет обещания, соответствующие Promises/A+ [57] 1.1 спецификация
- Dojo Toolkit дает обещания [58] и Twisted отсрочки в стиле
- МочиКит [59] вдохновлен альбомом Deferreds Twisted
- jQuery Отложенный объект основан на дизайне CommonJS Promises/A .
- AngularJS [60]
- узел -обещание [61]
- Q, автор Крис Коваль, соответствует Promises/A+ 1.1. [62]
- RSVP.js соответствует Promises/A+ 1.1. [63]
- ЮИ [64] класс обещаний [65] соответствует спецификации Promises/A+ 1.0.
- Bluebird, by Petka Antonov [66]
- Пакет замыканий библиотеки обещаний соответствует спецификации Promises/A+.
- См. список Promise/A+ для получения дополнительных реализаций, основанных на дизайне Promise/A+.
- Для Явы :
- JDeferred предоставляет API отложенного обещания и поведение, аналогичное JQuery .Deferred. объекту [67]
- ПарСек [68] предоставляет API-интерфейс Task Promise, идеально подходящий для асинхронной конвейерной обработки и ветвления, поддерживаемый LinkedIn.
- Для Луа :
- Модуль cqueues [1] содержит Promise API.
- Для Objective-C : MAFuture, [69] [70] RXPromise, [71] ObjC-CollapsingFutures, [72] ОбещаниеКит, [73] объект-обещание, [74] ОАОбещание, [75]
- Для OCaml : модуль Lazy реализует ленивые явные фьючерсы. [76]
- Для Perl : будущее, [77] Обещания, [78] Рефлекс, [79] Обещание::ES6, [80] и обещание::XS [81]
- Для PHP : Реагировать/Обещать [82]
- Для Питона :
- Для Р :
- Для Руби :
- Для ржавчины :
- фьючерсы-rs [93]
- Для Скалы :
- Утилитная библиотека Twitter [94]
- Для Свифта :
- Async-фреймворк, реализует стиль C#.
async
/неблокирующийawait
[95] - БудущийКит, [96] реализует версию для Apple GCD [97]
- FutureLib, чистая библиотека Swift 2, реализующая фьючерсы и обещания в стиле Scala с отменой в стиле TPL. [98]
- Deferred, чистая библиотека Swift, вдохновленная Deferred из OCaml. [99]
- BrightFutures [100]
- SwiftCoroutine [101]
- Async-фреймворк, реализует стиль C#.
- Для Tcl : tcl-обещание [102]
Сопрограммы [ править ]
Фьючерсы могут быть реализованы в сопрограммах [27] или генераторы , [103] что приводит к одной и той же стратегии оценки (например, совместная многозадачность или ленивая оценка).
Каналы [ править ]
Фьючерсы легко реализовать в каналах : фьючерс — это одноэлементный канал, а обещание — это процесс, который отправляет в канал, исполняя будущее. [104] [105] Это позволяет реализовывать фьючерсы на параллельных языках программирования с поддержкой каналов, таких как CSP и Go . Полученные фьючерсы являются явными, поскольку доступ к ним должен быть получен путем чтения из канала, а не только путем оценки.
См. также [ править ]
- Волокно (информатика)
- Фьютекс
- Пирамида гибели (программирование) , антипаттерн дизайна, которого избегают обещаниями
Ссылки [ править ]
- ^ Фридман, Дэниел; Дэвид Уайз (1976). Влияние прикладного программирования на многопроцессорность . Международная конференция по параллельной обработке. стр. 263–272.
Предварительная версия: Фридман, Дэниел; Уайз, Дэвид (апрель 1978 г.). «Аспекты прикладного программирования для параллельной обработки». Транзакции IEEE на компьютерах . С-27 (4): 289–296. CiteSeerX 10.1.1.295.9692 . дои : 10.1109/tc.1978.1675100 . S2CID 16333366 . - ^ Хиббард, Питер (1976). Средства параллельной обработки . Новые направления в алгоритмических языках, (ред.) Стивен А. Шуман, IRIA, 1976.
- ^ Генри Бейкер; Карл Хьюитт (август 1977 г.). Инкрементная сборка мусора процессов . Материалы симпозиума по языкам программирования искусственного интеллекта. Уведомления ACM SIGPLAN 12, 8. стр. 55–59. Архивировано из оригинала 4 июля 2008 года . Проверено 13 февраля 2015 г.
- ^ Конвейеризация обещаний на erights.org
- ^ Конвейеризация обещаний на вики C2
- ^ Jump up to: Перейти обратно: а б Барбара Лисков; Люба Шрира (1988). «Обещания: лингвистическая поддержка эффективных асинхронных вызовов процедур в распределенных системах». Материалы конференции SIGPLAN '88 по разработке и реализации языков программирования; Атланта, Джорджия, США . АКМ. стр. 260–267. дои : 10.1145/53990.54016 . ISBN 0-89791-269-1 . Также опубликовано в Уведомлениях ACM SIGPLAN 23 (7).
- ^ Надежные обещания с отсрочкой Додзё , Site Pen, 3 мая 2010 г.
- ^ Jump up to: Перейти обратно: а б «Обещание» , Руководство Алисы , DE: Uni-SB, заархивировано из оригинала 8 октября 2008 г. , получено 21 марта 2007 г.
- ^ Jump up to: Перейти обратно: а б «Future» , руководство Алисы , DE: Uni-SB, заархивировано из оригинала 6 октября 2008 г. , получено 21 марта 2007 г.
- ^ Обещание , E права
- ^ 500 строк или меньше, «Веб-сканер с сопрограммами asyncio» А. Джесси Джирью Дэвис и Гвидо ван Россум говорят, что «реализация использует asyncio.Event вместо Future, показанного здесь. Разница в том, что событие можно сбросить, тогда как Будущее не может перейти от решенного обратно к ожидающему».
- ^ Control Concurrent MVar , Haskell, заархивировано из оригинала 18 апреля 2009 г.
- ^ WaitNeeded , Моцарт Оз, заархивировано из оригинала 17 мая 2013 г. , получено 21 марта 2007 г.
- ^ Обещание , Sunless Sea, архивировано из оригинала 23 октября 2007 г.
- ^ Аргус , Массачусетский технологический институт
- ^ Лисков, Барбара (26 января 2021 г.), Распределенные вычисления и Argus , Устная история, IEEE GHN
- ^ Золото , Уданакс, архивировано из оригинала 11 октября 2008 г.
- ^ Трубопровод , E права
- ^ Генри Либерман (июнь 1981 г.). «Предварительный просмотр акта 1». Памятка MIT AI 625 .
- ^ Генри Либерман (июнь 1981 г.). «Думать о множестве вещей одновременно, не запутываясь: параллелизм в акте 1». Памятка MIT AI 626 .
- ^ Гетц, Брайан (23 ноября 2004 г.). «Параллелизм в JDK 5.0» . ИБМ .
- ^ Jump up to: Перейти обратно: а б «Async в 4.5: стоит того, чтобы ждать – блог .NET – главная страница сайта – блоги MSDN» . Блоги.msdn.com . Проверено 13 мая 2014 г.
- ^ Jump up to: Перейти обратно: а б с «Асинхронное программирование с использованием Async и Await (C# и Visual Basic)» . Msdn.microsoft.com . Проверено 13 мая 2014 г.
- ^ Томаш Петричек (29 октября 2010 г.). «Асинхронные C# и F# (I.): одновременное введение» .
- ^ Дон Сайм; Томас Петричек; Дмитрий Ломов (21 октября 2010 г.). «Модель асинхронного программирования F #, PADL 2011» .
- ^ Jump up to: Перейти обратно: а б Гилад Браха (октябрь 2014 г.). «Поддержка асинхронности языка Dart: этап 1» .
- ^ Jump up to: Перейти обратно: а б «PEP 0492 — Сопрограммы с синтаксисом async и await» .
- ^ Кенджиро Таура; Сатоши Мацуока; Акинори Ёнезава (1994). «ABCL / f: основанный на будущем полиморфный типизированный параллельный объектно-ориентированный язык - его дизайн и реализация». В материалах семинара DIMACS по спецификации параллельных алгоритмов, номер 18 в серии Dimacs по дискретной математике и теоретической информатике . Американское математическое общество. стр. 275–292. CiteSeerX 10.1.1.23.1161 .
- ^ «Dart SDK dart async Completer» .
- ^ "Задача" .
- ^ Стив Декорте (2005). «Ио, язык программирования» .
- ^ «Использование обещаний» . Сеть разработчиков Mozilla . Проверено 23 февраля 2021 г.
- ^ «Упрощение асинхронного программирования с помощью async и await» . Сеть разработчиков Mozilla . Проверено 23 февраля 2021 г.
- ^ Рич Хики (2009). «changes.txt в версии 1.1.x из Clojure richhickey» . Гитхаб .
- ^ «Будущее – язык программирования Kotlin» .
- ^ Сейф Хариди; Нильс Франзен. «Учебник страны Оз» . Глобальная пользовательская библиотека Моцарта. Архивировано из оригинала 14 мая 2011 года . Проверено 12 апреля 2011 г.
- ^ Выпуск Python 3.2
- ^ Выпуск Python 3.5
- ^ «Параллелизм с фьючерсами» . ПЛТ . Проверено 2 марта 2012 г.
- ^ «Обещание класса» . raku.org . Проверено 19 августа 2022 г.
- ^ «Будущее в std::future — Rust» . doc.rust-lang.org . Проверено 16 декабря 2023 г.
- ^ Common Lisp Blackbird
- ^ Common Lisp Eager Future2
- ^ Lisp параллельно - библиотека параллельного программирования для Common Lisp.
- ^ Common Lisp PCall
- ^ «Глава 30. Поток 4.0.0» . Проверено 26 июня 2013 г.
- ^ «Библиотека Dlib C++ #thread_pool» . Проверено 26 июня 2013 г.
- ^ «GitHub – facebook/folly: библиотека C++ с открытым исходным кодом, разработанная и используемая в Facebook» . Гитхаб . 8 января 2019 г.
- ^ «ХПХ» . 10 февраля 2019 г.
- ^ «Слайды тем POCO» (PDF) .
- ^ «QtCore 5.0: Класс QFuture» . Проект Qt. Архивировано из оригинала 1 июня 2013 года . Проверено 26 июня 2013 г.
- ^ «Морская звезда» . Проект Сетар . Проверено 22 августа 2016 г.
- ^ «stlab — это продолжающаяся работа того, что раньше называлось Лабораторией программных технологий Adobe. Исходные библиотеки Adobe (ASL), библиотеки платформ и новые библиотеки stlab размещены на github» . 31 января 2021 г.
- ^ Groovy GPars. Архивировано 12 января 2013 г. в Wayback Machine.
- ^ Куджо.js
- ^ JavaScript, когда.js
- ^ Обещания / Спецификация A +
- ^ обещания
- ^ JavaScript MochKit.Async
- ^ JavaScript Angularjs
- ^ JavaScript-обещание узла
- ^ «JavaScript Q» . Архивировано из оригинала 31 декабря 2018 года . Проверено 8 апреля 2013 г.
- ^ JavaScript RSVP.js
- ^ Библиотека классов YUI JavaScript
- ^ Класс обещаний YUI JavaScript
- ^ JavaScript Bluebird
- ^ Java JDeferred
- ^ Java ParSeq
- ^ Objective-C MAFuture GitHub
- ^ Objective-C MAFuture mikeash.com
- ^ Objective-C RXPromise
- ^ ObjC-CollapsingFutures
- ^ Objective-C PromiseKit
- ^ Objective-C objc-обещание
- ^ Objective-C OAPromise
- ^ OCaml Ленивый
- ^ Перл Будущее
- ^ Обещания Perl
- ^ Перл-рефлекс
- ^ Обещание Perl::ES6
- ^ «Promise::XS — Быстрые обещания в Perl — Metacpan.org» . Metacpan.org . Проверено 14 февраля 2021 г.
- ^ Реакция PHP/обещание
- ^ Встроенная реализация Python
- ^ Pythonfutures
- ^ «Искаженные отсрочки» . Архивировано из оригинала 6 августа 2020 года . Проверено 29 апреля 2010 г.
- ^ Будущее пакета R
- ^ будущее
- ^ Параллельный Рубин
- ^ Камень Рубинового обещания
- ^ Рубиновая библиотека
- ^ «Рубиновый целлулоид» . Архивировано из оригинала 8 мая 2013 года . Проверено 19 февраля 2022 г.
- ^ Будущий ресурс Ruby
- ^ ящик Futures-RS
- ^ Библиотека утилит Twitter
- ^ «Быстрая асинхронность» . Архивировано из оригинала 31 декабря 2018 года . Проверено 23 июня 2014 г.
- ^ Swift FutureKit
- ^ Swift Apple GCD
- ^ Swift FutureLib
- ^ bignerdranch/Отложенный
- ^ Томвис/BrightFutures
- ^ Белозьеров/SwiftCoroutine
- ^ tcl-обещание
- ^ Решает ли async/await реальную проблему?
- ^ «Языковые шаблоны Go Фьючерсы» . Архивировано из оригинала 4 декабря 2020 года . Проверено 9 февраля 2014 г.
- ^ «Языковые шаблоны Go» . Архивировано из оригинала 11 ноября 2020 года . Проверено 9 февраля 2014 г.