Сбой при использовании Mono.Tasklets.Continuation - PullRequest
0 голосов
/ 15 июля 2010

Я пытаюсь работать с библиотекой для передачи микропотоков в C #, используя mono.Начиная с Mono 2.4 или около того, очевидно, что продолжения (не выход) были доступны в разделе «Mono.Tasklets».Однако у них нет какой-либо документации, которую я могу найти, и хотя мое общее использование их работает, я иногда получаю (но воспроизводимый) сбой, к которому отладчик не присоединяется.

Мои конкретные вопросы:

Кто-нибудь знает, что такое функция Mark (), и где / когда мне нужно ее вызвать?Кажется, это однократная инициализация, но я не знаю, почему это не будет в конструкторе.

Есть ли ограничения на использование нескольких продолжений?Я обнаружил, что вы не можете передать продолжение другому потоку, но, похоже, я могу сохранить несколько продолжений и переключаться назад и вперед?

1 Ответ

2 голосов
/ 24 июля 2010

LE: Относительно проблемы сбоя см. Следующие открытые ошибки: Ошибка 566324 , Ошибка 580791 , Ошибка 602502

Я сам новичок в этом, я представляю здесь информацию, которую я собрал до сих пор. Может быть, это будет полезно.

1) Библиотека Mono.Tasklets (описанная Мигелем де Иказа [READ: здесь ]) является библиотекой продолжения, которую можно использовать для создания различных форм систем продолжения и потоков с малым весом (LW). .

Простой способ изобразить это - Mono-версия longjmp / setjmp на C, они могут использоваться только для размотки стека.

Библиотека изначально была разработана парнем [READ: здесь ], а теперь она включена в Mono и задокументирована [READ: здесь ] (перейдите по этим ссылкам, и вы найдете больше информации)

Этот парень реализовал библиотеку Microthreading поверх этой абстракции. и теперь это было перенесено в платформу Mono.Tasklets

2) Продолжением является объект, который можно использовать для хранения текущего состояния выполнения, а затем его можно использовать для восстановления сохраненного состояния позже.

Здесь «состояние выполнения» означает стек, который включает в себя стек вызовов и локальные переменные, а также регистры процессора.

Когда восстановленное состояние восстановлено, выполнение программы выглядит так, как будто оно возвращается назад в положение, в котором было сохранено состояние, со всеми локальными переменными, восстановленными.

Пример на языке C. и дополнительная информация о Wikipedia / Continuations

3) API:

public class Continuation {
      public Continuation ();
      public void Mark ();
      public int Store (int state);
      public void Restore (int state);
 }

Продолжения могут использоваться для реализации микропотоков . Вы можете посмотреть код из Mono.MicroThreads, доступный на Github [ЧИТАТЬ: здесь ]

    public Continuation()
    {
        m_handle = alloc_continuation();
        Print("Continuation()");
    }

    public void Mark()
    {
        Print("Mark()");
        // skip 1 frame, ie. this function
        mark_continuation_frame(m_handle, 1);
    }

    public int Store(int data)
    {
        Print("Store({0})", data);
        int res = store_continuation(m_handle, data);
        Print("Store({0}) = {1}", data, res);
        return res;
    }

    public void Restore(int data)
    {
        Print("Restore({0})", data);
        restore_continuation(m_handle, data);
        Print("Restore() exit (NEVER REACHED)");
    }

Из того, что представлено здесь :

Метка () используется для маркировки самого верхнего кадра, который будет сохранен

Store (x) сохраняет текущее состояние в продолжение и возвращает заданное целое число x.

Restore (y) восстанавливает сохраненное состояние и возвращает заданное целое число y. (Обратите внимание, что целое число y, данное Restore, на самом деле возвращается из метода Store (), потому что это то место, где мы находимся после восстановления состояния.)

static void Main()
{
 Continuation c = new Continuation();
 c.Mark();
 int foo = 123;
 int val = c.Store(0);
 Console.WriteLine("{0} {1}", val, foo);
 foo = 321;
 if (val < 5)
     c.Restore(val + 1);
}

Когда вы вызываете Store (), записывается текущее состояние выполнения, и вы можете вернуться в это состояние, вызвав Restore ().

Вызывающая функция Store () сообщает, является ли это исходным хранилищем или точкой восстановления на основе результата из Store:

 var c = new Continuation ();
 ...

 switch (c.Store (0)){
 case 0:
      // First invocation
 case 1:
      // Restored from the point ahead.
 }
 ...
 // Jump back to the switch statement.
 c.Restore (1); 
...