代码之家  ›  专栏  ›  技术社区  ›  Nicholas M T Elliott

使用mono.tasklets.continue崩溃

  •  0
  • Nicholas M T Elliott  · 技术社区  · 15 年前

    我正在尝试使用mono在C中处理一个微线程消息传递库。从Mono 2.4开始,显然可以在“mono.tasklets”下继续使用(而不是生成)。但是,这些文档中没有我能找到的任何文档,尽管我对它们的一般使用是有效的,但我偶尔会遇到一个调试器无法附加的(但可复制的)崩溃。

    我的具体问题是:

    有人知道mark()函数是什么,我需要在哪里/什么时候调用它吗?这似乎是一次初始化,但我不知道为什么它不在构造函数中。

    使用多个延续有限制吗?我发现您不能将一个延续传递给另一个线程,但似乎我可以存储多个延续并来回切换?

    1 回复  |  直到 14 年前
        1
  •  2
  •   Alex Bitek Uhall    14 年前

    Le:关于崩溃问题,请参阅以下打开的错误: Bug 566324 , Bug 580791 , Bug 602502

    我自己对这个还比较陌生,我在这里介绍了迄今为止收集到的信息。也许它会有用。

    1)Mono.微线程库(由Miguel de Icaza描述[阅读: here ])是一个延续库,可用于构建各种形式的延续系统和轻量(LW)线程。

    一种简单的方法是用C的longjmp/setjmp的单版本来实现这一点,它们只能用于展开堆栈。

    图书馆最初是由一个人开发的[阅读: here ]现在它包含在Mono中并记录在案[阅读: here ](通过这些链接,您可以找到更多信息)

    那个家伙在这个抽象之上实现了一个微线程库。现在已经移植到mono.tasklets框架

    2)continuation是一个对象,可用于存储当前执行状态,随后可用于恢复存储状态。

    这里的“执行状态”是指包含调用堆栈和局部变量的堆栈,以及处理器的寄存器。

    当存储状态恢复后,程序的执行看起来像回到保存状态的位置,所有局部变量都恢复了。

    An example in C. 更多信息 Wikipedia/Continuations

    3)API是:

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

    可以使用延续来实现 微线程 . 您可以查看Github上提供的mono.microthreads中的代码[阅读: here ]

        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)");
        }
    

    从呈现的内容开始 在这里 :

    标记() 它用于标记要存储的最上面的帧

    存储(X) 将当前状态存储到延续,并返回给定的整数x。

    恢复(Y) 恢复存储状态,并返回给定的整数y。 (请注意,给定要还原的整数y实际上是从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()返回到此状态。

    调用方to 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);