我创建了自己的线程库...当然是一个简单的非抢占式库,其中线程按照调用的顺序执行。该计划的简要说明如下:
class Thread
{
static Thread sched;
/*called only once*/
static void init()
{
*create a context for sched thread*
static void schedule()
{
....
setcontext(current thread from the queue);
return if empty
}
Thread(function)
{
intializes the context via getcontext and sets the uc_link to the context of sched
and pushed into the queue and calls schedule function
}
单线程似乎很好。但是当我初始化两个线程对象时,只有其中一个正在执行。 我怀疑当第一个线程完成其工作时,它返回到schedule函数,当schedule函数看到队列为空时......它也返回。
但我观察到构造函数只为第一个线程调用一次!!为什么会这样?
如果我没有从constuctor调用schedule函数,而是定义一个像
这样的函数void start()
{
schedule();
}
并在所有线程初始化后调用它正确执行。但我不想使用这种方法..
请向我解释执行的路径和上述问题的解决方案 这是它的实际代码
class thread
{
static queue<thread> Q;
ucontext_t con;
int u_p;
int c_p;
static void init()
{
flag=0;
getcontext(&schd.con);
//cout<<"fgh\n";
schd.con.uc_link=0;
schd.con.uc_stack.ss_sp=malloc(ST_S);
schd.con.uc_stack.ss_size=ST_S;
makecontext(&schd.con, schd.schedule, 0);
}
static thread main, schd;
static int flag;
public:
thread()
{ }
thread(int i){ init(); }
static void schedule()
{
//cout<<"ii\n";
if(Q.empty()){
flag=0;
return;
}
main=Q.front();
Q.pop();
setcontext(&main.con);
init();
//cout<<"yea\n";
}
thread(void (*fn)(), int u_p=15)
{
getcontext(&con);
con.uc_link=&schd.con;
con.uc_stack.ss_sp=malloc(ST_S);
con.uc_stack.ss_flags=0;
con.uc_stack.ss_size=ST_S;
makecontext(&con, fn, 0);
//cout<<"hjkl\n";
Q.push(*this);
if(flag==0){
flag=1;
schedule();
}
}
static void start(){ schedule(); }
};
queue<thread> thread::Q;
thread thread::main;
thread thread::schd;
int thread::flag;
答案 0 :(得分:0)
似乎正在发生这种情况:
Thread::Thread()
来电Thread::shedule()
Thread::shedule()
来电setcontext()
function
对象的Thread
我认为我看到的所有线程库和OS API都是创建线程挂起的,或者提供一个标志来创建处于挂起状态的线程。所以这是一个很好的方法,否则你会在创建另一个时失去当前的线程。此外,由于您使用轻量级线程,因此您几乎不得不创建没有任何标志的线程,以便能够从主线程创建多个线程。