Сопрограмма
в этой статье Использование внешних ссылок может не соответствовать политике и рекомендациям Википедии . ( Апрель 2024 г. ) |
Сопрограммы — это компоненты компьютерной программы , которые позволяют приостанавливать и возобновлять выполнение, обобщая подпрограммы для совместной многозадачности . Сопрограммы хорошо подходят для реализации знакомых программных компонентов, таких как совместные задачи , исключения , циклы событий , итераторы , бесконечные списки и каналы .
Их описывают как «функции, выполнение которых можно приостановить». [1]
Мелвин Конвей ввёл термин «сопрограмма» в 1958 году, когда применил его к построению ассемблерной программы . [2] Первое опубликованное объяснение сопрограммы появилось позже, в 1963 году. [3]
Определение и виды [ править ]
Не существует единого точного определения сопрограммы. В 1980 году Кристофер Д. Марлин [4] суммировали две широко признанные фундаментальные характеристики сопрограммы:
- значения данных, локальных для сопрограммы, сохраняются между последовательными вызовами;
- выполнение сопрограммы приостанавливается, когда управление покидает ее, только для продолжения с того места, где оно было остановлено, когда управление снова входит в сопрограмму на более позднем этапе.
Кроме того, реализация сопрограммы имеет 3 особенности:
- механизм передачи управления. асимметричные сопрограммы обычно предоставляют такие ключевые слова, как
yield
иresume
. Программисты не могут свободно выбирать, какому кадру уступить. Среда выполнения уступает только ближайшему вызывающему объекту текущей сопрограммы. С другой стороны, в симметричных сопрограммах программисты должны указать пункт назначения доходности. - предусмотрены ли в языке сопрограммы как первоклассные объекты , которыми программист может свободно манипулировать, или как ограниченные конструкции;
- может ли сопрограмма приостановить свое выполнение из вызовов вложенных функций. Такая сопрограмма является стековой сопрограммой . Другой вариант называется сопрограммой без стека , где, если она не помечена как сопрограмма, обычная функция не может использовать ключевое слово
yield
.
Пересмотр сопрограмм [5] опубликованный в 2009 году термин « полная сопрограмма» предложен для обозначения сопрограммы, которая поддерживает первоклассную сопрограмму и является стековой. Полные сопрограммы заслуживают собственного названия, поскольку они обладают той же выразительной силой , что и одноразовые продолжения и продолжения с разделителями. Полные сопрограммы бывают симметричными или асимметричными. Важно отметить, что то, является ли сопрограмма симметричной или асимметричной, не влияет на то, насколько выразительной она может быть, поскольку они одинаково выразительны, хотя полные сопрограммы более выразительны, чем неполные сопрограммы. Хотя их выразительная сила одинакова, асимметричные сопрограммы больше напоминают структуры управления, основанные на подпрограммах, в том смысле, что управление всегда передается обратно вызывающей стороне, что программистам может показаться более знакомым.
Сравнение с [ править ]
Подпрограммы [ править ]
Подпрограммы — это частные случаи сопрограмм. [6] При вызове подпрограммы выполнение начинается с самого начала, а после завершения подпрограммы она завершается; экземпляр подпрограммы возвращает значение только один раз и не сохраняет состояние между вызовами. Напротив, сопрограммы могут завершиться, вызвав другие сопрограммы, которые позже могут вернуться к тому месту, где они были вызваны в исходной сопрограмме; с точки зрения сопрограммы, это не выход, а вызов другой сопрограммы. [6] Таким образом, экземпляр сопрограммы сохраняет состояние и меняется в зависимости от вызова; одновременно может существовать несколько экземпляров данной сопрограммы. Разница между вызовом другой сопрограммы посредством «уступки» ей и простым вызовом другой подпрограммы (которая затем также вернется в исходную точку) заключается в том, что отношения между двумя сопрограммами, которые уступают друг другу, не являются отношениями вызывающего -вызываемый, но вместо этого симметричный.
Любую подпрограмму можно преобразовать в сопрограмму, которая не вызывает выход . [7]
Вот простой пример того, чем могут быть полезны сопрограммы. Предположим, у вас есть отношения потребитель-производитель, где одна процедура создает элементы и добавляет их в очередь, а другая удаляет элементы из очереди и использует их. Из соображений эффективности вы хотите добавлять и удалять несколько элементов одновременно. Код может выглядеть так:
var q := new queue coroutine produce loop while q is not full create some new items add the items to q yield to consume coroutine consume loop while q is not empty remove some items from q use the items yield to produce call produce
Затем очередь полностью заполняется или очищается, прежде чем передать управление другой сопрограмме с помощью команды Выход . Дальнейшие вызовы сопрограмм начинаются сразу после выхода , во внешнем цикле сопрограммы.
Хотя этот пример часто используется как введение в многопоточность , два потока для этого не нужны: оператор урожайности можно реализовать путем перехода непосредственно из одной подпрограммы в другую.
Темы [ править ]
Сопрограммы очень похожи на потоки . Однако сопрограммы являются многозадачными совместно , тогда как потоки обычно являются многозадачными с вытеснением . Сопрограммы обеспечивают параллелизм , поскольку они позволяют выполнять задачи вне последовательности или в изменяемом порядке, без изменения общего результата, но они не обеспечивают параллелизм , поскольку не выполняют несколько задач одновременно. Преимущества сопрограмм перед потоками заключаются в том, что их можно использовать в контексте жесткого реального времени ( переключение между сопрограммами не требует каких-либо системных вызовов или каких- либо блокирующих вызовов), нет необходимости в примитивах синхронизации, таких как мьютексы , семафоры и т. д. для защиты критических разделов и отсутствия необходимости в поддержке со стороны операционной системы.
Можно реализовать сопрограммы с использованием потоков с упреждающим планированием таким образом, чтобы это было прозрачно для вызывающего кода, но некоторые преимущества (в частности, пригодность для работы в жестком реальном времени и относительная дешевизна переключения между ними) будут потеряны.
Генераторы [ править ]
Генераторы, также известные как полукорутины, [8] являются подмножеством сопрограмм. В частности, хотя обе могут выполнять несколько раз, приостанавливая свое выполнение и разрешая повторный вход в нескольких точках входа, они различаются способностью сопрограмм контролировать, где выполнение продолжается сразу после завершения, в то время как генераторы не могут, вместо этого передавая управление обратно вызывающей стороне генератора. . [9] То есть, поскольку генераторы в первую очередь используются для упрощения написания итераторов , то yield
Оператор в генераторе не указывает сопрограмму для перехода, а передает значение обратно в родительскую процедуру.
Тем не менее, по-прежнему возможно реализовать сопрограммы поверх генератора с помощью диспетчерской процедуры верхнего уровня ( по сути, трамплина ), которая явно передает управление дочерним генераторам, идентифицируемым токенами, переданными обратно от генераторов:
var q := new queue generator produce loop while q is not full create some new items add the items to q yield generator consume loop while q is not empty remove some items from q use the items yield subroutine dispatcher var d := new dictionary(generator → iterator) d[produce] := start produce d[consume] := start consume var current := produce loop call current current := next d[current] call dispatcher
Ряд реализаций сопрограмм для языков с поддержкой генераторов, но без собственных сопрограмм (например, Python [10] до 2.5) используйте эту или аналогичную модель.
Взаимная рекурсия [ править ]
Использование сопрограмм для конечных автоматов или параллелизма аналогично использованию взаимной рекурсии с хвостовыми вызовами , поскольку в обоих случаях элемент управления меняется на другой из набора подпрограмм. Однако сопрограммы более гибки и, как правило, более эффективны. Поскольку сопрограммы возвращают результат, а не возвращают его, а затем возобновляют выполнение, а не перезапускают его с самого начала, они могут удерживать состояние как переменных (как при замыкании), так и точки выполнения, а выходы не ограничиваются нахождением в хвостовой позиции; взаимно рекурсивные подпрограммы должны либо использовать общие переменные, либо передавать состояние в качестве параметров. Кроме того, каждый взаимно рекурсивный вызов подпрограммы требует нового кадра стека (если не реализовано устранение хвостового вызова ), тогда как передача управления между сопрограммами использует существующие контексты и может быть реализована простым переходом.
Общее использование [ править ]
Сопрограммы полезны для реализации следующего:
- Конечные автоматы внутри одной подпрограммы, где состояние определяется текущей точкой входа/выхода процедуры; это может привести к более читаемому коду по сравнению с использованием goto , а также может быть реализовано посредством взаимной рекурсии с хвостовыми вызовами .
- Актёрская модель параллелизма, например, в видеоиграх . У каждого актора есть свои процедуры (это опять-таки логически разделяет код), но они добровольно передают управление центральному планировщику, который выполняет их последовательно (это форма совместной многозадачности ).
- Генераторы , которые полезны для потоков – особенно ввода/вывода – и для общего обхода структур данных.
- Связь последовательных процессов , где каждый подпроцесс является сопрограммой. Канальные входы/выходы и операции блокировки создают сопрограммы, и планировщик разблокирует их по событиям завершения. Альтернативно, каждый подпроцесс может быть родительским для следующего за ним в конвейере данных (или предшествующего ему, и в этом случае шаблон может быть выражен как вложенные генераторы).
- Обратная связь, обычно используемая в математическом программном обеспечении, где такая процедура, как решатель, интегральный вычислитель... требует использования процесса для выполнения вычислений, таких как вычисление уравнения или подынтегральной функции.
Встроенная поддержка [ править ]
Сопрограммы возникли как метод языка ассемблера , но поддерживаются некоторыми языками программирования высокого уровня .
- Айкидо
- АнгелСкрипт
- Балерина
- БКПЛ
- Паскаль (Borland Turbo Pascal 7.0 с модулем uThreads)
- БЕТА
- БЛАЖЕНСТВО
- С++ (начиная с C++20)
- С# (начиная с версии 2.0)
- Часовня
- ЧакК
- КЛУ
- Д
- Динамический С
- Эрланг
- Ф#
- Фактор
- Скрипт GameMonkey
- GDScript (язык сценариев Годо)
- Идти
- Хаскелл [11] [12]
- Ассамблея высокого уровня [13]
- Икона
- Этот
- JavaScript (начиная с версии 1.7, стандартизирован в ECMAScript 6) [14] ECMAScript 2017 также включает ожидания . поддержку
- Юлия [15]
- Котлин (начиная с версии 1.1) [16]
- Лимбо
- Два [17]
- Ясный
- микроС++
- Модуль-2
- Немерль
- Perl 5 (с использованием модуля Coro )
- PHP (с HipHop , родной начиная с PHP 5.5)
- Пиколис
- Пролог
- Python (начиная с версии 2.5, [18] с улучшенной поддержкой с версии 3.3 и с явным синтаксисом с версии 3.5. [19] )
- Ракетка (язык программирования)
- Раку [20]
- Руби
- Сатер
- Схема
- Себя
- С 67 лет [21]
- Смолток
- Белка
- Бесстековый Python
- СуперКоллайдер [22]
- Ткл (начиная с версии 8.6)
- городской пейзаж
Поскольку продолжения для реализации сопрограмм можно использовать , поддерживающие их языки программирования также могут довольно легко поддерживать сопрограммы.
Реализации [ править ]
По состоянию на 2003 год [update]Многие из наиболее популярных языков программирования, включая C и его производные, не имеют встроенной поддержки сопрограмм в языке или его стандартных библиотеках. Во многом это связано с ограничениями реализации подпрограмм на основе стека . Исключением является библиотека C++ Boost.Context , входящая в состав библиотек boost , которая поддерживает замену контекста на ARM, MIPS, PowerPC, SPARC и x86 в POSIX, Mac OS X и Windows. Сопрограммы могут быть построены на Boost.Context.
В ситуациях, когда сопрограмма была бы естественной реализацией механизма, но недоступна, типичным ответом является использование замыкания — подпрограммы с переменными состояния ( статическими переменными , часто логическими флагами) для поддержания внутреннего состояния между вызовами и передать управление в нужную точку. Условные выражения внутри кода приводят к выполнению различных путей кода при последовательных вызовах в зависимости от значений переменных состояния. Другой типичный ответ — реализация явного конечного автомата в форме большого и сложного оператора переключения или с помощью оператора перехода , в частности, вычисляемого перехода . Такие реализации считаются трудными для понимания и поддержки и являются мотивацией для поддержки сопрограмм.
Потоки и, в меньшей степени , волокна являются сегодня альтернативой сопрограммам в основных средах программирования. в реальном времени Потоки предоставляют средства для управления совместным взаимодействием одновременно выполняющихся фрагментов кода . Потоки широко доступны в средах, поддерживающих C (и поддерживаются изначально во многих других современных языках), знакомы многим программистам и обычно хорошо реализованы, хорошо документированы и хорошо поддерживаются. Однако, поскольку они решают большую и сложную проблему, они включают в себя множество мощных и сложных средств и, соответственно, требуют сложного обучения. Таким образом, когда все, что необходимо, — это сопрограмма, использование потока может оказаться излишним.
Одним из важных различий между потоками и сопрограммами является то, что потоки обычно планируются заранее, а сопрограммы — нет. Поскольку потоки могут быть перепланированы в любой момент и могут выполняться одновременно, программы, использующие потоки, должны быть осторожны с блокировкой . Напротив, поскольку сопрограммы можно перепланировать только в определенных точках программы и они не выполняются одновременно, программы, использующие сопрограммы, часто могут полностью избежать блокировки. Это свойство также считается преимуществом событийно-управляемого или асинхронного программирования.
Поскольку волокна планируются совместно, они обеспечивают идеальную основу для реализации описанных выше сопрограмм. [23] Однако системная поддержка волокон часто отсутствует по сравнению с поддержкой потоков.
С [ править ]
Для реализации сопрограмм общего назначения второй стек вызовов необходимо получить , что не поддерживается языком C напрямую . Надежный (хотя и специфичный для платформы) способ добиться этого — использовать небольшой объем встроенной сборки для явного управления указателем стека во время первоначального создания сопрограммы. Это подход, рекомендованный Томом Даффом в обсуждении его относительных преимуществ по сравнению с методом, используемым Protothreads . [24] [ нужен неосновной источник ] На платформах, которые предоставляют POSIX системный вызов sigaltstack , второй стек вызовов можно получить, вызвав функцию трамплина из обработчика сигнала. [25] [26] для достижения той же цели в переносимом C ценой некоторой дополнительной сложности. Библиотеки C, соответствующие POSIX или Единой спецификации Unix (SUSv3), предоставляют такие процедуры, как getcontext, setcontext, makecontext и swapcontext , но эти функции были объявлены устаревшими в POSIX 1.2008. [27]
Как только второй стек вызовов будет получен одним из перечисленных выше методов, функции setjmp и longjmp в стандартной библиотеке C можно будет использовать для реализации переключения между сопрограммами. Эти функции сохраняют и восстанавливают, соответственно, указатель стека , программный счетчик , сохраненные вызываемым абонентом , регистры , и любое другое внутреннее состояние, как того требует ABI , так что возврат к сопрограмме после возврата восстанавливает все состояние, которое будет восстановлено при возврате. из вызова функции. Минималистские реализации, которые не используют функции setjmp и longjmp, могут достичь того же результата с помощью небольшого блока встроенного ассемблера , который меняет местами только указатель стека и программный счетчик и затирает все остальные регистры. Это может быть значительно быстрее, поскольку setjmp и longjmp должны консервативно хранить все регистры, которые могут использоваться в соответствии с ABI, тогда как метод clobber позволяет компилятору хранить (путем передачи в стек) только то, что, как он знает, действительно используется.
Из-за отсутствия прямой языковой поддержки многие авторы написали свои собственные библиотеки для сопрограмм, которые скрывают вышеуказанные детали. Библиотека libtask Расса Кокса [28] хороший образец этого жанра. Он использует функции контекста, если они предоставляются встроенной библиотекой C; в противном случае он предоставляет свои собственные реализации для ARM, PowerPC, Sparc и x86. Другие известные реализации включают libpcl, [29] хор, [30] лнить, [31] libCoroutine, [32] libconcurrency, [33] свободное сердце, [34] ребра2, [35] либдилл., [36] либако, [37] и Либко. [26]
В дополнение к общему подходу, описанному выше, было предпринято несколько попыток аппроксимировать сопрограммы в C комбинациями подпрограмм и макросов. Саймона Тэтэма , Вклад [38] основанный на устройстве Даффа , является ярким примером жанра и является основой для Protothreads и подобных реализаций. [39] В дополнение к возражениям Даффа, [24] Собственные комментарии Тэтэма дают откровенную оценку ограничений этого подхода: «Насколько мне известно, это худший образец хакерства на языке C, когда-либо виденный в серьезном производственном коде». [38] Основные недостатки этого приближения заключаются в том, что из-за отсутствия отдельного кадра стека для каждой сопрограммы локальные переменные не сохраняются при выходе из функции, невозможно иметь несколько записей в функции, а управление можно получить только из рутина высшего уровня. [24]
С++ [ править ]
- В C++20 представлены стандартизированные сопрограммы как функции без стека, которые можно приостанавливать в середине выполнения и возобновлять позже. Приостановленное состояние сопрограммы хранится в куче. [40] Реализация этого стандарта продолжается: компиляторы G++ и MSVC в настоящее время полностью поддерживают стандартные сопрограммы в последних версиях. [41]
- concurrencpp — библиотека C++20, которая обеспечивает стороннюю поддержку сопрограмм C++20 в виде awaitable-задач и исполнителей, которые их запускают.
- Boost.Coroutine — созданная Оливером Ковальке, является официальной портативной библиотекой сопрограмм boost, начиная с версии 1.53. Библиотека использует Boost.Context и поддерживает ARM, MIPS, PowerPC, SPARC и X86 в POSIX, Mac OS X и Windows.
- Boost.Coroutine2 — также созданная Оливером Ковальке, представляет собой модернизированную переносимую библиотеку сопрограмм, начиная с версии boost 1.59. Он использует возможности C++11, но удаляет поддержку симметричных сопрограмм.
- Мордор . В 2010 году Mozy открыл исходный код библиотеки C++, реализующей сопрограммы, с упором на их использование для абстрагирования асинхронного ввода-вывода в более знакомую последовательную модель. [42]
- CO2 — безстековая сопрограмма, основанная на приемах препроцессора C++ , обеспечивающая эмуляцию ожидания/выхода.
- ScummVM — проект ScummVM реализует облегченную версию бесстековых сопрограмм на основе статьи Саймона Тэтэма .
- tonbit::coroutine — реализация асимметричной сопрограммы C++11 в формате .h через ucontext/fiber
- Сопрограммы появились в Clang в мае 2017 года, реализация libc++ продолжается. [43]
- Эль от Докера
- oatpp-coroutines — сопрограммы без стека с планированием, предназначенные для операций ввода-вывода с высоким уровнем параллелизма. Используется в 5 миллионами подключений WebSocket эксперименте Oat++ с . Часть веб-фреймворка Oat++ .
С# [ править ]
В C# 2.0 добавлена функциональность полусопрограммы ( генератора ) посредством шаблона итератора и yield
ключевое слово. [44] [45] C# 5.0 включает поддержку синтаксиса ожидания . Кроме того:
- Платформа MindTouch Dream REST обеспечивает реализацию сопрограмм на основе шаблона итератора C# 2.0.
- Платформа шаблонов экрана Caliburn . ( архивировано 19 января 2013 г. в archive.today ) для WPF использует итераторы C# 2.0 для упрощения программирования пользовательского интерфейса, особенно в асинхронных сценариях
- Библиотека Power Threading ( архивировано 24 марта 2010 г. на Wayback Machine ) Джеффри Рихтера реализует AsyncEnumerator, который обеспечивает упрощенную модель асинхронного программирования с использованием сопрограмм на основе итераторов.
- Игровой движок Unity реализует сопрограммы.
- Servelat Pieces Проект Евгения Боброва обеспечивает прозрачную асинхронность для сервисов Silverlight WCF и возможность асинхронного вызова любого синхронного метода. Реализация основана на итераторе Caliburn Coroutines и блоках итераторов C#.
- StreamThreads — это легкая библиотека сопрограмм C# с открытым исходным кодом, основанная на методах расширения итератора. Он поддерживает обработку ошибок и возвращаемые значения.
Кложур [ править ]
Cloroutine — сторонняя библиотека, обеспечивающая поддержку бесстековых сопрограмм в Clojure . Он реализован как макрос, статически разбивающий произвольный блок кода на произвольные вызовы var и выдающий сопрограмму как функцию с состоянием.
Д [ править ]
D реализует сопрограммы в качестве класса стандартной библиотеки. Fiber A Генератор упрощает представление функции волокна в качестве входного диапазона , делая любое волокно совместимым с существующими алгоритмами диапазона.
Иди [ править ]
В Go есть встроенная концепция « горутин », которые представляют собой легкие, независимые процессы, управляемые средой выполнения Go. Новую горутину можно запустить с помощью ключевого слова «go». Каждая горутина имеет стек переменного размера, который можно расширять по мере необходимости. Горутины обычно взаимодействуют, используя встроенные каналы Go. [46] [47] [48] [49]
Ява [ править ]
существует несколько реализаций сопрограмм В Java . Несмотря на ограничения, налагаемые абстракциями Java, JVM не исключает такой возможности. [50] Используются четыре общих метода, но два из них нарушают переносимость байт-кода среди JVM, соответствующих стандартам.
- Модифицированные JVM. Можно создать исправленную JVM для более естественной поддержки сопрограмм. Для JVM Da Vinci были созданы исправления. [51]
- Модифицированный байт-код. Функциональность сопрограммы возможна путем переписывания обычного байт-кода Java либо на лету, либо во время компиляции. Наборы инструментов включают Javaflow , Java Coroutines и Coroutines .
- Механизмы JNI, специфичные для платформы. Они используют методы JNI, реализованные в библиотеках ОС или C, для обеспечения функциональности JVM. [ нужна ссылка ]
- Абстракции потоков. Библиотеки сопрограмм, реализованные с использованием потоков, могут быть тяжеловесными, хотя производительность будет зависеть от реализации потоков JVM.
JavaScript [ править ]
- узлы-волокна
- Fibjs — fibjs — это среда выполнения JavaScript, созданная на базе JavaScript-движка Chrome V8. fibjs использует волоконно-переключатель , стиль синхронизации и неблокирующую модель ввода-вывода для создания масштабируемых систем.
- Начиная с ECMAScript 2015 , обеспечивается функциональность безстековых сопрограмм посредством «генераторов» и выражений доходности.
Котлин [ править ]
Kotlin реализует сопрограммы как часть собственной библиотеки.
Луа [ править ]
Lua поддерживает первоклассные стековые асимметричные сопрограммы начиная с версии 5.0 (2003 г.). [52] стандартной библиотеки в сопрограмме . [53] [54]
Модуль-2 [ править ]
Modula-2, как определено Виртом, реализует сопрограммы как часть стандартной библиотеки SYSTEM.
Процедура NEWPROCESS() заполняет контекст, заданный блоком кода и пространством для стека в качестве параметров, а процедура TRANSFER() передает управление сопрограмме, учитывая контекст сопрограммы в качестве параметра.
Моно [ править ]
Среда выполнения Mono Common Language поддерживает продолжения. [55] из которых могут быть построены сопрограммы.
.NET Framework [ править ]
Во время разработки .NET Framework 2.0 компания Microsoft расширила дизайн API-интерфейсов хостинга Common Language Runtime (CLR) для управления планированием на основе оптоволокна с прицелом на его использование в режиме оптоволокна для SQL-сервера. [56] Перед выпуском поддержка перехватчика переключения задач ICLRTask::SwitchOut была удалена из-за нехватки времени. [57] Следовательно, использование Fibre API для переключения задач в настоящее время не является приемлемым вариантом в .NET Framework. [ нужно обновить ]
OCaml [ править ]
OCaml поддерживает сопрограммы через свои Thread
модуль. [58] Эти сопрограммы обеспечивают параллелизм без параллелизма и заранее планируются для одного потока операционной системы. Начиная с OCaml 5.0, зеленые потоки также доступны ; обеспечивается различными модулями.
Перл [ править ]
Сопрограммы встроены во все серверные части Raku . [59]
PHP [ править ]
- Волокна встроены начиная с PHP 8.1.
- Амфхп
- Открыть Свул
- Сопрограмма реализована способом, напоминающим функции Python и некоторые Go , многие примеры показывают код, преобразованный с тем же количеством строк и поведением.
Питон [ править ]
- Python 2.5 реализует лучшую поддержку функций, подобных сопрограммам, на основе расширенных генераторов ( PEP 342 ).
- Python 3.3 улучшает эту возможность, поддерживая делегирование подгенератору ( PEP 380 ).
- Python 3.4 представляет комплексную структуру асинхронного ввода-вывода, стандартизированную в PEP 3156 , которая включает сопрограммы, использующие делегирование подгенератора.
- В Python 3.5 представлена явная поддержка сопрограмм с async/ await синтаксисом ( PEP 0492 ).
- Начиная с Python 3.7, async/await стали зарезервированными ключевыми словами. [60]
- Ивентлет
- Гринлет
- джентльмен
- бесстековый питон
Ракетка [ править ]
Racket предоставляет собственные продолжения с тривиальной реализацией сопрограмм, представленных в официальном каталоге пакетов. Реализация С. Де Габриэль
Руби [ править ]
- Ruby 1.9 изначально поддерживает сопрограммы, которые реализованы как волокна , которые являются полусопрограммами. [61]
- Реализация Марка Де Шимакера.
- Ruby 2.5 и выше изначально поддерживают сопрограммы, которые реализованы как волокна.
- Реализация Томаса Брэнсона
Схема [ править ]
Поскольку Scheme обеспечивает полную поддержку продолжений, реализация сопрограмм почти тривиальна и требует только поддержания очереди продолжений.
Смолток [ править ]
Поскольку в большинстве сред Smalltalk стек выполнения является первоклассным, сопрограммы могут быть реализованы без дополнительной поддержки библиотек или виртуальных машин.
Язык команд инструмента (Tcl) [ править ]
Начиная с версии 8.6, язык команд инструментов поддерживает сопрограммы на основном языке. [62]
Вала [ править ]
Vala реализует встроенную поддержку сопрограмм. Они предназначены для использования с основным циклом Gtk, но могут использоваться отдельно, если позаботиться о том, чтобы конечный обратный вызов никогда не вызывался перед выполнением хотя бы одного выхода.
Языки ассемблера [ править ]
Машинно-зависимые языки ассемблера часто предоставляют прямые методы для выполнения сопрограмм. Например, в MACRO-11 , языке ассемблера семейства миникомпьютеров PDP-11 , «классическое» переключение сопрограммы осуществляется с помощью инструкции «JSR PC,@(SP)+», которая переходит по адресу, полученному из текущей ( т. е ) . следующей стек и помещает в стек адрес инструкции. В VAXen (в VAX MACRO ) сопоставимой инструкцией является «JSB @(SP)+». Даже на Motorola 6809 есть инструкция "JSR[,S++]"; обратите внимание на «++», поскольку 2 байта (адреса) извлекаются из стека. Эта инструкция часто используется в (стандартном) «мониторном» Assist 09.
См. также [ править ]
- Асинхронный/ожидание
- Pipeline — своего рода сопрограмма, используемая для связи между программами. [63]
- Protothreads — облегченная реализация потока без стека, использующая механизм, подобный сопрограмме.
Ссылки [ править ]
- ^ «Как, черт возьми, работает async/await в Python 3.5?» . Высокий, язвительный канадец . 11 февраля 2016 г. Проверено 10 января 2023 г.
- ^ Кнут, Дональд Эрвин (1997). Фундаментальные алгоритмы (PDF) . Искусство компьютерного программирования. Том. 1 (3-е изд.). Аддисон-Уэсли. Раздел 1.4.5: История и библиография, стр. 229. ISBN. 978-0-201-89683-1 . Архивировано (PDF) из оригинала 21 октября 2019 г.
- ^ Конвей, Мелвин Э. (июль 1963 г.). «Проектирование компилятора разделимых диаграмм переходов» (PDF) . Коммуникации АКМ . 6 (7). АКМ: 396–408. дои : 10.1145/366663.366704 . ISSN 0001-0782 . S2CID 10559786 - через цифровую библиотеку ACM.
- ^ Марлин, Кристофер (1980). Сопрограммы: методология программирования, языковой дизайн и реализация . Спрингер. ISBN 3-540-10256-6 .
- ^ Ана Люсия де Моура; Роберто Иерусалимский (2009). «Возвращение к сопрограммам». Транзакции ACM в языках и системах программирования . 31 (2): 1–31. CiteSeerX 10.1.1.58.4017 . дои : 10.1145/1462166.1462167 . S2CID 9918449 .
- ^ Jump up to: Перейти обратно: а б Кнут, Дональд Эрвин (1997). Фундаментальные алгоритмы . Искусство компьютерного программирования. Том. 1 (3-е изд.). Аддисон-Уэсли. Раздел 1.4.2: Сопрограммы, стр. 193–200. ISBN 978-0-201-89683-1 .
- ^ Перлис, Алан Дж. (сентябрь 1982 г.). «Эпиграммы по программированию» . Уведомления ACM SIGPLAN . 17 (9): 7–13. дои : 10.1145/947955.1083808 . S2CID 20512767 . Архивировано из оригинала 17 января 1999 года.
6. Симметрия — это концепция снижения сложности (сопрограммы включают подпрограммы); ищи это везде
- ^ Энтони Ралстон (2000). Энциклопедия информатики . Природный паб. Группа. ISBN 978-1-56159-248-7 . Проверено 11 мая 2013 г.
- ^ См., например, Справочник по языку Python.
" https://docs.python.org/reference/expressions.html#yieldexpr 5.2.10. Выражения доходности]":
«Все это делает функции-генераторы очень похожими на сопрограммы; они выполняют несколько операций, имеют более одной точки входа, и их выполнение может быть приостановлено. Единственное отличие состоит в том, что функция-генератор не может контролировать, где должно продолжиться выполнение после завершения; управление всегда передается вызывающей стороне генератора». - ^ Мерц, Дэвид (1 июля 2002 г.). «Генераторные конечные автоматы» . Очаровательный питон . IBM DeveloperWorks. Архивировано из оригинала 28 февраля 2009 года . Проверено 2 февраля 2011 г.
- ^ «Сопрограмма: типобезопасные сопрограммы, использующие облегченные типы сеансов» .
- ^ «Сопрограммы в Haskell» .
- ^ «Модуль сопрограмм (coroutines.hhf)» . Руководство по стандартной библиотеке HLA .
- ^ «Новое в JavaScript 1.7» . Архивировано из оригинала 8 марта 2009 г. Проверено 18 июня 2018 г.
- ^ «Руководство Юлии — Поток управления — Задачи (также известные как сопрограммы)» .
- ^ «Что нового в Котлине 1.1» .
- ^ «Справочное руководство по Lua 5.2» . www.lua.org .
- ^ «Учебное пособие по Python async/await» . Злоупотребление стеком . 17 декабря 2015 г.
- ^ «8. Составные операторы — документация Python 3.8.0» . docs.python.org .
- ^ «Собрать и/или сопрограммы» . 19 декабря 2012 г.
- ^ Даль, О.Дж.; Хоар, CAR, ред. (1972). «Иерархические структуры программы». Структурное программирование . Лондон, Великобритания: Академическая пресса. стр. 175–220. ISBN 978-0-12-200550-3 .
- ^ Маккартни, Дж. «Переосмысление языка компьютерного музыкального программирования: SuperCollider» . Компьютерный музыкальный журнал, 26 (4): 61-68. МИТ Пресс, 2002.
- ^ Реализация сопрограмм для .NET путем упаковки неуправляемого Fiber API. Архивировано 7 сентября 2008 г. в Wayback Machine , Аджай Шанкар, журнал MSDN.
- ^ Jump up to: Перейти обратно: а б с «Сопрограммы в C – мозговоз» . 5 марта 2005 г.
- ^ Ральф С. Энгельшалл (18–23 июня 2000 г.). Портативная многопоточность: трюк со стеком сигналов для создания потоков в пользовательском пространстве (PS) . Ежегодная техническая конференция USENIX. Сан-Диего, США.
- ^ Jump up to: Перейти обратно: а б "либко" . code.byuu.org . [ постоянная мертвая ссылка ]
- ^ «getcontext(3) — страница руководства Linux» . man7.org .
- ^ http://swtch.com/libtask/ — библиотека сопрограмм libtask Расса Кокса для FreeBSD, Linux, Mac OS X и SunOS.
- ^ Портативная библиотека сопрограмм — библиотека C, использующая возможности POSIX/SUSv3.
- ^ http://www.goron.de/~froese/coro/. Архивировано 10 января 2006 г. в Wayback Machine — библиотека coro Эдгара Торнига для x86, Linux и FreeBSD.
- ^ https://github.com/halayli/lthread — lthread — это многоядерная/многопоточная библиотека сопрограмм, написанная на C.
- ^ «libcoroutine: переносимая реализация сопрограммы» . Архивировано из оригинала 12 ноября 2019 г. Проверено 6 сентября 2013 г. для FreeBSD, Linux, OS X PPC и x86, SunOS, Symbian и других
- ^ «libconcurrency — масштабируемая библиотека параллелизма для C» . простая библиотека C для портативных сопрограмм переключения стека
- ^ «libcoro: C-библиотека, которая реализует сопрограммы (совместную многозадачность) портативным способом» . используется в качестве основы для Perl-модуля Coro.
- ^ «RIBS (Надежная инфраструктура для серверных систем) версия 2: aolarchive/ribs2» . 13 августа 2019 г. – через GitHub.
- ^ "либдилл" . libdill.org . Архивировано из оригинала 2 декабря 2019 г. Проверено 21 октября 2019 г.
- ^ «Невероятно быстрая и легкая библиотека асимметричных сопрограмм C 💎 ⛅🚀⛅🌞: hnes/libaco» . 21 октября 2019 г. – через GitHub.
- ^ Jump up to: Перейти обратно: а б Саймон Тэтэм (2000). «Сопрограммы в C» .
- ^ «Реализация бесстековой сопрограммы в C и C++: jsseldenthuis/coroutine» . 18 марта 2019 г. – через GitHub.
- ^ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4680.pdf - Техническая спецификация сопрограмм.
- ^ https://en.cppreference.com/w/cpp/compiler_support#cpp20 — текущая поддержка компилятором стандартных сопрограмм.
- ^ http://mozy.com/blog/announcements/open-source-and-mozy-the-debut-of-mozy-code/ - Открытый исходный код и Mozy: дебют кода Mozy
- ^ https://twitter.com/eric01/status/867473461836263424 - EricWF: Сопрограммы теперь в Clang Trunk! Сейчас работаю над реализацией Libc++.
- ^ Вагнер, Билл (11 ноября 2021 г.). «Итераторы» . Документация С# . Microsoft – через Microsoft Learn.
- ^ Вагнер, Билл (13 февраля 2023 г.). «История C#» . Документация С# . Майкрософт . C# версии 2.0 – через Microsoft Learn.
- ^ «Горутины — Эффективное Go» . go.dev . Проверено 28 ноября 2022 г.
- ^ «Операторы Go — Спецификация Go» . go.dev . Проверено 28 ноября 2022 г.
- ^ «Горутины — экскурсия по Го» . go.dev . Проверено 28 ноября 2022 г.
- ^ «Часто задаваемые вопросы (FAQ) — язык программирования Go» . go.dev .
- ^ Лукас Стадлер (2009). «Продолжение JVM» (PDF) . Языковой саммит JVM.
- ^ Реми Форакс (19 ноября 2009 г.). «Черт возьми: у JVM есть сопрограмма/продолжение/волокно и т. д.» . Архивировано из оригинала 19 марта 2015 года.
- ^ «История версий Lua» . Луа.орг .
- ^ де Моура, Ана Люсия; РОДРИГЕС, Ноэми; Иерусалимский, Роберто. «Сопрограммы в Lua» (PDF) . Луа.орг . Проверено 24 апреля 2023 г.
- ^ де Моура, Ана Люсия; РОДРИГЕС, Ноэми; Иерусалимский, Роберто (2004). «Сопрограммы в Lua». Журнал универсальной информатики . 10 (7): 901-924.
- ^ http://www.mono-project.com/Continuations Моно-продолжения
- ^ http://blogs.msdn.com/cbrumme/archive/2004/02/21/77595.aspx , Крис Брамме, веб-журнал cbrumme
- ^ кексугит (15 сентября 2005 г.). «Режим оптоволокна пропал…» docs.microsoft.com . Проверено 8 июня 2021 г.
- ^ «Библиотека потоков» .
- ^ «РФК №31» .
- ^ «Что нового в Python 3.7» . Проверено 10 сентября 2021 г.
- ^ «полусопрограммы» . Архивировано из оригинала 24 октября 2007 года.
- ^ «Страница руководства по сопрограмме — Встроенные команды Tcl» . Tcl.tk. Проверено 27 июня 2016 г.
- ^ Ричи, Деннис М. (1980). «Эволюция системы разделения времени Unix». Языковой дизайн и методология программирования . Конспекты лекций по информатике. Том. 79. С. 25–35. дои : 10.1007/3-540-09745-7_2 . ISBN 978-3-540-09745-7 . S2CID 571269 . Архивировано из оригинала 8 апреля 2015 г. Проверено 26 января 2011 г.
Дальнейшее чтение [ править ]
- Ана Люсия де Моура; Роберто Иерусалимский (2004). «Возвращение к сопрограммам». Транзакции ACM в языках и системах программирования . 31 (2): 1–31. CiteSeerX 10.1.1.58.4017 . дои : 10.1145/1462166.1462167 . S2CID 9918449 .
Внешние ссылки [ править ]
- Всестороннее введение Саймона Тэтэма ориентированное на C. в сопрограммы,
- Страница сопрограмм Softpanorama - содержит обширные ссылки на сопрограммы ассемблера.