0

私は独自のスレッドライブラリを作成しました...もちろん、スレッドが呼び出された順序で実行される単純な非プリエンプティブライブラリです。プログラムの概要は次のとおりです。

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;
4

1 に答える 1

0

これが起こっているようです:

  1. あなたは新しいスレッドを作成します
  2. Thread::Thread()通話Thread::shedule()
  3. Thread::shedule()通話setcontext()
  4. function新しいThreadオブジェクトの制御フロー スイッチ
  5. この新しいスレッドは親コンテキストに戻らずに実行されるため、別のスレッドを作成することはできません

私が見たすべてのスレッド ライブラリと OS API は、中断されたスレッドを作成するか、中断された状態でスレッドを作成するためのフラグを提供していると思います。そうしないと、別のスレッドを作成するときに現在のスレッドを停止できなくなります。さらに、軽量スレッドを使用するため、メインのスレッドから複数のスレッドを作成できるようにするために、フラグなしで中断されたスレッドを作成することをほとんど余儀なくされます。

于 2012-08-25T05:07:22.563 に答える