2010-07-05

Интересная задачка: вытесняющий мультипроцессинг в userland

Нужно в рамках одной нити управления реализовать поочередно работающие 2 "процесса" (скажем, вычисление 2-х функций), переключение между которыми происходит по регулярному сигналу таймера. Естественно, что при переключении состояние вычисления должно сохраняться и восстанавливаться на следующем такте (а не начинаться заново каждый раз).

Интересно было бы увидеть, как это реализовывается в разных языках? (Я так понимаю, что в Smalltalk это должно быть тривиально за счет наличия объекта контекста. А где еще?)

7 comments:

turtle said...

Я так понимаю, что в лиспах и функциональных языках это можно реализовать в контекстах замыканий. Вроде как на Scala в http://code.google.com/p/swarm-dpl/ именно так и делают распределённую модель вычислений.

Anonymous said...

На сях такое вполне можно реализовать, надо только немного аккуратно заниматься перключением стеков.
Например, http://state-threads.sourceforge.net/
http://code.google.com/p/libconcurrency/

Anonymous said...

>можно реализовать в контекстах замыканий

Тут нужны не замыкания, а продолжения. Вот только у продолжений интересное взаимодействие с динамическими областями действия...

Vsevolod Dyomkin said...

@dmitry-vk в том то и дело, что продолжения — это, насколько я понимаю, лексический объект, а в данном случае (как я это вижу) нужен динамический.

State Threads посмотрю, спасибо. А вот с libconcurrency уже сразу есть вопрос: я так понимаю, там нужно coro_call вызвать из контекста другой корутины, а мне нужно из обработчика сигнала, в который будет передаваться текущий прерванный контекст (условно говоря, отложенный restart) — можно ли там такое сделать?

@turtle т.е. на delimited-continuations (как в Scala или CL-Weblocks) я не совсем представляю, как это сделать, поскольку нужно иметь доступ к стеку в runtime

Vsevolod Dyomkin said...

fix: ну т.е. не weblocks, конечно, а cl-cont, который в weblocks используется

turtle said...

@dmitry-vk да, продолжения, конечно же.

Anonymous said...

>там нужно coro_call вызвать из контекста другой корутины

Не знаю, я нагуглил их :)

Продолжения - это как раз и есть стек нити (стек вызовов, стек динамических переменных, стек деструкторов и прочие стеки, формуирующие динамический контекст) или его кусок. Если весь стек - то получаем полное continuation, если кусок - то delimited continuation.

В случае всяких cl-cont и других CPS-преобразователей мы не имеем доступа к стеку, поэтому эмулируем его (cps-преобразование и есть эмуляция стека).

Зеленые нити реализуются следующим образом: выделяется новый стек для зеленой нити, а переключение нитей выполняется через смену контекста нити (например, longjmp; в обработчиках сигналов можно использовать siglongmp).