Сравнивайте с английским: нажмите на абзац — оригинал откроется в окне. Кнопка EN под абзацем показывает его прямо в тексте.
Введение
Протопоток — это механизм с низкими накладными расходами для конкурентного программирования. Протопотоки функционируют как потоки или корутины без стека, обеспечивая недорогой блокирующий контекст, используя минимальный объем памяти на протопоток (порядка единиц байт). Протопотоки используются для реализации формы невытесняющей конкурентности, известной как кооперативная многозадачность, и, следовательно, не требуют переключения контекста при уступке управления другому потоку. Внутри протопотока уступка управления достигается с помощью конструкции Даффа в функции потока и внешней переменной, используемой в операторе switch. Это позволяет переходить (возобновлять выполнение) из точки уступки при очередном вызове функции. Для блокировки потоков эти уступки могут быть защищены условием, так что последовательные вызовы одной и той же функции будут приводить к уступке управления, пока условие защиты не станет истинным. Особенностью протопотоков по сравнению с другими реализациями корутин или полноценных потоков является отсутствие стека. Это имеет свои преимущества и недостатки. Недостатком является то, что нельзя полагаться на сохранение значений локальных переменных протопотока после уступки управления другому контексту. Они должны сохранять свое состояние с помощью статических или внешних, часто глобальных, переменных. Преимуществом является их малый вес, что делает их полезными в системах с сильно ограниченной памятью, таких как небольшие микроконтроллеры, где другие решения непрактичны или менее предпочтительны. Том Дафф, автор конструкции Даффа, так отозвался о недостатках этого метода: «Существует похожий трюк для автоматов с конечными состояниями, управляемых прерываниями, который слишком сложен для описания. [ ] Я никогда не считал это адекватной реализацией корутин общего назначения, поскольку сложно иметь несколько одновременных активаций корутины, и невозможно, используя этот метод, чтобы корутины могли уступить управление где-либо, кроме как в своей основной процедуре. Простая библиотека переключения стеков на языке ассемблера позволяет делать и то, и другое». Концепция протопотока была разработана Адамом Данкельсом и Оливером Шмидтом на основе предыдущих работ Саймона Татама и Тома Даффа.
A protothread is a low overhead mechanism for concurrent programming. Protothreads function as stackless, lightweight threads, or coroutines, providing a blocking context cheaply using minimal memory per protothread (on the order of single bytes). Protothreads are used to accomplish a non preempted form of concurrency known as cooperative multitasking and, therefore, do not incur context switch when yielding to another thread. Within a protothread, yielding is accomplished by utilizing Duff's device within a thread's function and an external variable used in within the switch statement. This allows jumping (resuming) from a yield upon another function call. In order to block threads, these yields may be guarded by a conditional so that successive calls to the same function will yield unless the guard conditional is true. A feature of protothreads relative to other implementations of coroutines, or proper threads, is that they are stackless. This has advantages and disadvantages. A disadvantage is that local variables within the protothread cannot be trusted to have retained their values across a yield to another context. They must retain their state through the use of static or external, often global, variables. An advantage is that they are very lightweight and therefore useful on severely memory constrained systems like small microcontrollers where other solutions are impractical or less desirable. Tom Duff, of Duff's device fame, had this to say about the shortcomings of the method: "a similar trick for interrupt driven state machines that is too horrible to go into. [ ] I never thought it was an adequate general purpose coroutine implementation because it’s not easy to have multiple simultaneous activations of a coroutine and it’s not possible using this method to have coroutines give up control anywhere but in their top level routine. A simple assembly language stack switching library lets you do both of those." The protothread concept was developed by Adam Dunkels and Oliver Schmidt, based on prior work by Simon Tatham and Tom Duff.