C:使用ucontext/浮点异常的多线程(内核转储)
我正在尝试使用ucontext例程来实现多线程库。 运行这段代码时,我得到了“浮点异常(内核转储)”C:使用ucontext/浮点异常的多线程(内核转储),c,multithreading,C,Multithreading,我正在尝试使用ucontext例程来实现多线程库。 运行这段代码时,我得到了“浮点异常(内核转储)” #include <stdio.h> #include <stdlib.h> #include <ucontext.h> typedef struct { ucontext_t context; }MyThread; #define MAX 10 MyThread queue[MAX]; int rear=0,front=0; void addT
#include <stdio.h>
#include <stdlib.h>
#include <ucontext.h>
typedef struct {
ucontext_t context;
}MyThread;
#define MAX 10
MyThread queue[MAX];
int rear=0,front=0;
void addToQueue(MyThread t)
{
if(rear==MAX)
{
printf("Queue is full!");
return;
}
queue[front]=t;
front+=1;
}
MyThread* removeFromQueue()
{
if(front==rear)
return NULL;
rear=rear+1;
return &(queue[rear-1]);
}
static void func12(void)
{
printf("func12: started\n");
}
static MyThread umain;
MyThread MyThreadCreate (void(*start_funct)(void *), void *args)
{
MyThread newthread;
getcontext(&(newthread.context));
char stck[30];
newthread.context.uc_stack.ss_sp =stck;
newthread.context.uc_stack.ss_size = sizeof(stck);
newthread.context.uc_link =&(umain.context);
printf("Inside the mythreadcreate before makecontext \n");
makecontext(&newthread.context,**(void(*)(void))start_funct,1, args);**
printf("Inside the mythreadcreate after makecontext \n");
addToQueue(newthread);
return newthread;
}
void MyThreadYield(void)
{
MyThread* a=removeFromQueue();
printf("Before swapping the context \n");
swapcontext(&umain.context,&(a->context));
printf("After the swapping the context \n");
}
int main(void)
{
int i=0;
printf("Inside the main \n");
MyThreadCreate(func12,&i);
//getcontext(&(umain.context));
MyThreadYield();
}
更新:在函数调用中添加了(void(*)(void))start_funct,1,args)。删除了不必要的函数调用。分配给newthread上下文的堆栈是第一个问题:
char stck[30];
newthread.context.uc_stack.ss_sp =stck;
“stck”在MyThreadCreate
函数的堆栈上分配。一旦函数返回,它就超出范围,因此newthread.context.uc_stack.ss_sp
指向原始线程堆栈中的某个内存
具体地说,newthread和新的原始线程在该点“共享”相同的堆栈,这会导致核心转储(它们可能会覆盖自身)。
为newthread.context.uc\u stack.ss\u sp
和malloc
分配适当的内存
现在。堆栈本质上包含要执行的代码指令。
当执行上下文时,这将导致程序失败
上面的链接给出了如何允许内存段包含要执行的代码的指示。
或者,一个简单的解决方案是使用堆栈上的一些内存,这些内存在上下文不再使用之前不会被丢弃(例如,
main
中声明的数组)。忽略对MyThreadInit(func1,&i)的调用;你试过在调试器中运行它吗?你能为多线程程序推荐任何调试器吗?Gdb是有效的。只要运行程序,当它崩溃时,执行线程应用所有回溯。我不是多线程专家。。。但是有什么理由不使用pthreads吗?看:谢谢你的解释!你能推荐一些好的调试器来测试多线程程序吗?我试着用上面提到的建议运行代码,现在出现了一个分段错误(而不是浮点异常)。我还尝试全局定义变量,但它仍然存在分段错误。我编辑了我的答案,添加了第二个我忽略的问题,与ucontext本身的使用有更深层的关系。希望这会有所帮助。对于第二部分,我没有使用从中返回的函数的上下文。因此,我所期望的上下文不是来自createcontext,而是来自与quese中的上下文交换的yield()。(swapcontext保存当前上下文,然后切换到其他上下文)。对于第一部分,我尝试在main中声明堆栈并将其传递给函数,但问题仍然存在。所以我开始将变量和函数声明为静态的。在进行排列之后,我发现了主要的问题。我刚刚在mythreadcreate中将“newthread”声明为静态,它现在正在工作。我正在尝试思考它,但仍然不确定为什么会这样。可以是在整个程序期间存储的静态变量。但现在另一个问题是“没有声明为静态的堆栈怎么样?”。那个堆栈真的被使用了吗?或者它以某种方式存储在主静态变量结构中!
char stck[30];
newthread.context.uc_stack.ss_sp =stck;