有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,需要找出哪个上下文处于活动状态并将其放在队列末尾,然后将控件传递给另一个上下文
答案 0 :(得分:0)
- 我可以找出哪个上下文当前处于活动状态吗?
这对于getcontext()
来说是微不足道的,但是您真正想了解的是在 激活 Manager 之前哪个上下文处于活动状态。而且您不能这样做(除非旧的上下文会将信息存储在全局变量中)。
- 我能否以某种方式将ucontext作为参数从一个函数传递给另一个函数。
因为函数参数只能在函数入口传递给 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_t
,N1
的数组,可以轻松地将其扩展到两个以上的上下文。
答案 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