我正在做下个学期的作业。它要求我们使用ucontext API实现自己的上下文切换/线程库。教授提供了执行该操作的代码,但是在线程返回之前,他手动进行了一些工作并调用一个ISR,该ISR查找要使用的另一个线程并与之交换上下文,如果没有上下文,则退出。
分配的重点是使用上下文的uc_link字段,以便当它返回返回值时就可以完成工作。我已经创建了一个函数(类型为void/void args),该函数可以完成该函数之前所做的工作(清理然后调用ISR)。教授说他想要这个。
所以剩下的就是在uc_link字段中的上下文中的某个地方做一个makecontext,以便它运行我的线程,对吗?好吧,当我对ucontext_t和函数的任何组合进行makecontext时,我遇到了segfault,而gdb无法提供任何帮助。我可以跳过makecontext,并且当它在我创建的线程中遇到返回值时,程序会“正常”退出,因为(大概是)uc_link字段未正确设置(这是我正在尝试的操作)。
我也找不到关于为什么makecontext会出现段错误的任何信息。有人可以帮忙吗?
stack2.ss_sp = (void *)(malloc(STACKSIZE));
if(stack2.ss_sp == NULL){
printf("thread failed to get stack space\n");
exit(8);
}
stack2.ss_size = STACKSIZE;
stack2.ss_flags = 0;
if(getcontext(&main_context) == -1){
perror("getcontext in t_init, rtn_env");
exit(5);
}
//main_context.uc_stack = t_state[i].mystk;
main_context.uc_stack = stack2;
main_context.uc_link = 0;
makecontext(&main_context, (void (*)(void))thread_rtn, 0);
我也尝试过thread_rtn,&thread_rtn和其他东西。将thread_rtn声明为void thread_rtn(void)。稍后,在每个线程中(run_env的类型为ucontext_t):
...
t_state[i].run_env.uc_link = &main_context;
最佳答案
这里有很多事情,但我会尽力而为。我也试图在不解决家庭作业的情况下回答这个问题。
在什么情况下声明了thread_rtn
,它是否使用任何非静态变量?
该段故障可能是由已分配但不再可用的内存(上下文无关或已释放)引起的。
我不知道main_context
是否与线程上下文相同,两者应该不同。
看起来每个线程都需要自己的堆栈,该堆栈不应与主上下文的堆栈(或与其他线程的堆栈相同的sam)相同。考虑每个线程可以在哪里获取内存以用作堆栈。在什么情况下malloc(STACKSIZE)
将返回NULL
?
将线程上下文添加到主上下文后,应增加main_context.uc_link
。看来main_context.uc_link
一直在跟踪链接到主上下文的线程数。想一想当计数减少时会发生什么(我想留下一些与类(class)相关的工作,而不是说减少计数该怎么做)。请注意特殊值0,这意味着不再有与此主上下文关联的任何线程。 main_context.uc_link
是否有最大值?
希望这可以帮助。
关于c - makecontext segfault?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4548132/