我正在尝试创建线程库。为此,我正在尝试实现队列来存储要执行的待处理线程。
#include <ucontext.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct {
ucontext_t context;
}MyThread;
#define MAX 20
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]);
}
MyThread umain;
void MyThreadInit (void(*start_funct)(void *), void *args)
{
getcontext(&(umain.context));
char p[64000];
umain.context.uc_stack.ss_sp =(char *)p;
umain.context.uc_stack.ss_size = sizeof(p);
umain.context.uc_link =NULL;
makecontext(&umain.context,(void(*)(void))start_funct,1,args);
setcontext(&(umain.context));
}
MyThread MyThreadCreate (void(*start_funct)(void *), void *arg)
{
MyThread newthread;
char args[10000];
getcontext(&(newthread.context));
newthread.context.uc_stack.ss_sp =(char *)args;
newthread.context.uc_stack.ss_size = sizeof(args);
newthread.context.uc_link =NULL;
makecontext(&newthread.context,(void(*)(void))start_funct,1,arg);
addToQueue(newthread);
return newthread;
}
void MyThreadYield(void)
{
MyThread* a=removeFromQueue();
MyThread save;
if(a != NULL)
{
printf("Before yielding the context \n");
getcontext(&(save.context));
addToQueue(save);
//swapcontext(&umain.context,&(a->context));
setcontext(a);
printf("After the swapping the context \n");
}
else
{ printf("NULL!!! \n");
}
}
void func1(void *arg)
{
printf("func1started \n");
MyThreadYield();
}
void func2(void *arg)
{
printf("func2started \n");
MyThreadYield();
}
void func12(void *arg)
{
printf("func12started \n");
MyThreadCreate(func1,arg);
MyThreadCreate(func2,arg);
MyThreadYield();
}
int main(void)
{
int i=0;
printf("inside the main function \n");
MyThreadInit(func12,&i);
return 0;
}
Output :
inside the main function
func12started
Before yielding the context
func1started
Before yielding the context
func2started
Before yielding the context
func1started
Before yielding the context
Segmentation fault
我之所以提到队列,是因为我尝试通过从“MyThreadYield”函数中删除下面的代码来进行试验,它工作正常,但没有达到预期的功能。
getcontext(&(save.context)); 添加队列(保存);