我如何知道哪个上下文处于活动状态?

时间:2019-05-06 17:21:14

标签: c++ linux ucontext

有2个问题。 1.我可以找出哪个上下文当前处于活动状态吗?
2.我能否以某种方式将ucontext从一个函数传递给另一个函数作为参数。 我想做这样的事情。:

    //Instead of this


      #include <pthread.h>
    #include <iostream>
    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <ucontext.h>
    #include <queue>

    #define MEM 64000
    #define MEMS 16000
    #define MEL 32000
    using namespace std;
    ucontext_t N1,N2, Main;

    void fn1()
    {
    for(int i=0;i<=3;i++){
    cout<<i<<ndl;
    swapcontext(&N1,&N2);
    }
    }

    void fn2()
    { 
    for(int i=4;i<=7;i++){
    cout<<i<<endl;
    if(i==7)
    swapcontext(&N2,&Main);
    else
    swapcontext(&N2,&N1);
    }
    }
     int main(int argc, char *argv[])
    {
    getcontext(&Main);
    getcontext(&N1);
    getcontext(&N2);
    N1.uc_link=0;
    N1.uc_stack.ss_sp=malloc(MEM);
    N1.uc_stack.ss_size=MEM;
    N2.uc_link=0;
    N2.uc_stack.ss_sp=malloc(MEMS);
    N2.uc_stack.ss_size=MEMS;
    makecontext(&N1, fn1, 0);
    makecontext(&N2, fn2, 0);
    swapcontext(&Main,&N1);
    printf("completed\n");
    exit(0);
    }
        //Do something like this

        void fn1()
        {
        for(int i=0;i<=3;i++){
        cout<<i<<endl;
        swapcontext(&N1,&Man);
        }
        }

        void fn2()
        { 
        for(int i=4;i<=7;i++){
        cout<<i<<endl;
        if(i==7)
        swapcontext(&N2,&Main);
        else
        swapcontext(&N2,&Man);
        }


       void Manager()// void Manager(ucontext_t u)??? and makecontext(&Man,(void(*)())Manager,1,...)
        {
        //which ucontext transferred control ?
         queue <ucontext> q;
        push.active_context;
        ...
        swapcontext(&Man,&another_context);
        }

通常,您需要创建一个其中有一个队列的Manager,需要找出哪个上下文处于活动状态并将其放在队列末尾,然后将控件传递给另一个上下文

2 个答案:

答案 0 :(得分:0)

  
      
  1. 我可以找出哪个上下文当前处于活动状态吗?
  2.   

这对于getcontext()来说是微不足道的,但是您真正想了解的是在 激活 Manager 之前哪个上下文处于活动状态。而且您不能这样做(除非旧的上下文会将信息存储在全局变量中)。

  
      
  1. 我能否以某种方式将ucontext作为参数从一个函数传递给另一个函数。
  2.   

因为函数参数只能在函数入口传递给 Manager ,并且 Manager 不会在其开始时重新输入,而是从{{ 1}},您不能这样做。

要通过 Manager 传递控制权,您可以做的是让它确定要激活哪个上下文,例如。 g。

swapcontext()

通过使用void Manager() { ucontext_t *another_context = &N1; // begin with N1 for (;; another_context = another_context == &N1 ? &N2 : &N1) // switch context swapcontext(&Man, another_context); } 而不是ucontext_tN1的数组,可以轻松地将其扩展到两个以上的上下文。

答案 1 :(得分:0)

  

是否可以通过队列对某人进行?也就是说,从中获取控件的上下文放在末尾,然后将控件转移到另一个控件(即开头)。

实际上,管理器不必是上下文,它可以是普通函数。而且由于无论如何队列都必须是全局的(以便main()可以排队执行上下文),因此 Manager 不需要传递任何参数。因此, Manager 和执行功能可以看起来像e。 g。:

queue <ucontext *> q;
void Manager()
{
    ucontext_t *active_context = q.front(); // active context is at queue front
    q.pop();                                // remove active context from front
    q.push(active_context);                 // insert active context at the end
    swapcontext(active_context, q.front()); // switch to the new active context
}

void fn1()
{
    for (int i=0; i<=3; i++)
    {
        cout<<i<<endl;
        Manager();
    }
}

void fn2()
{ 
    for (int i=4; i<=7; i++)
    {
        cout<<i<<endl;
        Manager();
    }
}

从功能中删除何时切换回 Main 上下文的决定-而是在main()中通过设置N1.uc_link = &Main;来完成,并开始执行通过:

    q.push(&N1);
    q.push(&N2);
    swapcontext(&Main, q.front());  // switch to first context