【问题标题】:How do I know which context is active?我如何知道哪个上下文处于活动状态?
【发布时间】:2019-05-06 17:21:13
【问题描述】:

有 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,里面会有一个队列,你需要找出哪个上下文是活动的,放在队列的末尾,把控制权交给另一个上下文

【问题讨论】:

  • 1) 在这个,咳咳,上下文中定义“上下文”。 2) 发布minimal reproducible example。目前还不清楚你在问什么。
  • format你的代码很好。你现在看到的东西真的很难读。

标签: c++ linux ucontext


【解决方案1】:
  1. 我可以找出当前处于活动状态的上下文吗?

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

  1. 我能否以某种方式传入一个 ucontext,从一个函数到另一个函数作为参数。

由于函数参数只能在函数入口时传递给 Manager,并且 Manager 在开始时不会重新输入,而是从 @987654322 返回@,你不能那样做。

通过 Manager 实现控制传递的方法是让它确定要激活的上下文,例如。 g.

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_t 数组而不是N1N2 轻松扩展到两个以上的上下文。

【讨论】:

  • 非常感谢,我会尝试实现类似的东西。是否可以通过队列对某人进行操作?也就是说,获取控件的上下文放在最后,然后将控件转移到另一个上下文,也就是在开头的上下文。 PS:如何用数组做类似的事情?
  • 这是我无法完成的任务。收到控制功能后,Manager决定将控制权移交给哪个工作功能;决定如下: - 挂起的工作函数的描述符被放置在描述符队列的末尾; - 从描述符队列的开头检索工作函数的描述符; - 这个函数被转移控制。
  • @AlexChek - 我写了另一个答案,它使用了任意数量的上下文队列。对数组做类似的事情只是意味着将上下文放入数组中并移动元素或保持头尾索引 - 等效,只是不那么优雅。
【解决方案2】:

是否可以通过队列对某人进行此操作?也就是说,获取控件的上下文放在最后,然后将控件转移到另一个上下文中,这个上下文应该在开头。

实际上,Manager 不一定是context,它可以是一个普通的函数。而且由于队列必须是全局的(以便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 = &amp;Main; 来完成,并通过以下方式开始执行:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-07
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    • 2013-05-20
    相关资源
    最近更新 更多