私は独自のスレッドライブラリを作成しました...もちろん、スレッドが呼び出された順序で実行される単純な非プリエンプティブライブラリです。プログラムの概要は次のとおりです。
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
}
シングルスレッドですべてがうまくいくようです。しかし、2つのスレッドオブジェクトを初期化すると、そのうちの1つだけが実行されます。最初のスレッドがジョブを完了すると、schedule関数に戻り、schedule関数がキューが空であることを確認すると...それも戻ります。
しかし、コンストラクターが最初のスレッドに対して1回だけ呼び出されることを確認しました。どうしてこんなことに?
コンストラクターからスケジュール関数を呼び出さない場合は、代わりに次のような関数を定義します。
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;