在xv6中使用jmp_buf数组实现线程调度的报错问题
使用多个jmp_buf实现调度时的错误排查
我尝试用jmp_buf数组实现线程调度,在xv6环境下编译运行,预期输出3 2 1,但运行时出现错误。
预期输出
3 2 1
示例代码
struct threads{ jmp_buf env; }; int main(){ struct threads **t = (struct threads**) malloc(sizeof(struct threads*)*3); for (int i = 0; i < 3; i++){ if (setjmp(t[i]->env)!=0){ printf("%d ",i); if (i+1<3) longjmp(t[i+1]->env,-1); } } longjmp(t[0]->env,-1); return 0; }
错误信息
程序运行触发段错误(Segmentation Fault)
问题分析与修复方案
空指针访问错误
你仅分配了存储指针的数组t,但每个t[i]并未指向实际的struct threads实例,直接访问t[i]->env会触发内存访问错误。需要在循环中为每个指针分配结构体内存:for (int i = 0; i < 3; i++){ t[i] = malloc(sizeof(struct threads)); // 新增内存分配逻辑 if (setjmp(t[i]->env)!=0){ // 原有逻辑 } }循环变量生命周期问题
当longjmp跳回setjmp位置时,循环变量i的值已经是循环结束后的3(而非调用setjmp时的0、1、2),会导致打印结果不符合预期。需要将任务ID保存到结构体中,避免依赖栈上的循环变量:
修改后的完整代码:
#include <stdio.h> #include <stdlib.h> #include <setjmp.h> struct threads{ jmp_buf env; int id; // 保存任务ID,避免依赖循环变量 }; int main(){ struct threads **t = malloc(sizeof(struct threads*)*3); for (int i = 0; i < 3; i++){ t[i] = malloc(sizeof(struct threads)); t[i]->id = 3 - i; // 对应预期输出的3、2、1 if (setjmp(t[i]->env)!=0){ printf("%d ", t[i]->id); if (i < 2) { longjmp(t[i+1]->env, -1); } return 0; } } longjmp(t[0]->env, -1); // 内存回收(xv6程序退出会自动回收,此处为规范写法) for (int i = 0; i <3; i++){ free(t[i]); } free(t); return 0; }
这段代码修复了空指针问题,同时通过结构体存储任务ID的方式规避了循环变量的生命周期陷阱,运行后会输出预期的3 2 1。
内容的提问来源于stack exchange,提问作者Chunhao
相关产品推荐
相关产品推荐

