Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C:使用ucontext/浮点异常的多线程(内核转储)_C_Multithreading - Fatal编程技术网

C:使用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

我正在尝试使用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 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;