2010-07-05

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

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

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

7 comments:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    ReplyDelete