所以我正在进行上下文切换以创建自己的线程库。我遇到了很多困难。我创建了一个队列,我存储了上下文,这样当一个进程产生时,它可能会在以后继续。然而,似乎我弹出的上下文是不正确的。我怀疑这可能是由于我的全局currentContext变量未正确分配?
ucontext_t* currentContext;
void system_init() {
createQueue();
isRunning = 0;
}
int uthread_create(void (* func)()) {
ucontext_t *context;
context = (ucontext_t*)malloc(sizeof(ucontext_t));
getcontext(context);
context->uc_stack.ss_sp = malloc(16384);
context->uc_stack.ss_size = 16384;
makecontext(context, func, 0);
if(isRunning == 0) {
isRunning = 1;
currentContext = context;
setcontext(context);
return 0;
}
else {
push(context);
return 0;
}
return -1;
}
int uthread_yield() {
push(currentContext);
currentContext = pop();
setcontext(currentContext);
}
以下是我的代码需要实现的方式:
int n threads=0;
int myid=0;
void do something()
{
int id;
id=myid;
myid++;
printf (”This is ult %d\n”, id); //just for demo purpose
if(n threads<5){
uthread create(do something);
n threads++;
printf (”ult %d yields \n”,id );
uthread yield ();
printf (”ult %d resumes \n”,id);
uthread create(do something);
n threads++;
}
printf (”ult %d starts I/O \n”,id);
uthread startIO();
sleep (2); //simulate some long−time I/O operation
uthread endIO();
printf (”ult %d returns from I/O \n”,id);
uthread exit ();
}
main()
{
int i ;
system init ();
uthread create(do something);
uthread exit ();
}
预期输出为:
This is ult 0
ult 0 yields
This is ult 1
ult 1 yields
ult 0 resumes
ult 0 starts I/O
This is ult 2
ult 2 yields
ult 1 resumes
ult 1 starts I/O
This is ult 3
ult 3 starts I/O
This is ult 4
ult 4 starts I/O
ult 2 resumes
ult 2 starts I/O
This is ult 5
ult 5 starts I/O
ult 0 returns from I/O
ult 1 returns from I/O
ult 3 returns from I/O
ult 4 returns from I/O
ult 2 returns from I/O
ult 5 returns from I/O
但是我的输出只是:
This is ult 0
ult 0 yields
This is ult 1
ult 1 yields
This is ult 2
ult 2 yields
This is ult 3
ult 3 yields
This is ult 4
ult 4 yields
This is ult 5
ult 5 starts I/O
ult 5 returns from I/O
这表明我的线程没有恢复,而只是被跳过。
答案 0 :(得分:1)
您似乎正在将数据类型ucontext_t
推送到队列中。这将创建您放入队列的context
的副本,这将导致问题,因为您在堆中搁置内存(更不用说放弃您创建的原始ucontext_t
)
尝试让您的队列存储类型为ucontext_t *
而非ucontext_t
的指针。这样,您就不会链接内存,并且可以在从队列中弹出上下文时访问最初创建的进程。