2012-08-25 38 views
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 
} 

每一件事似乎都與單線程罰款。但是當我初始化兩個線程對象時,只有其中一個正在執行。 我懷疑當第一個線程完成它的工作時,它會返回到日程安排函數,當日程安排函數看到隊列是空的時......它也會返回。

但我觀察到,第一個線程的構造函數只被調用一次!!爲什麼?

如果我不叫從constuctor日程安排功能,而不是我這樣定義

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

實際的代碼看起來像這種情況正在發生:

  1. 您創建一個新的線程
  2. Thread::Thread()電話Thread::shedule()
  3. Thread::shedule()電話setcontext()
  4. 控制流量開關到function新的Thread對象
  5. 這個新的線程執行,不切換回其父背景下,這樣另一個線程不能創建

我想我已經看到了要麼全部線程庫和操作系統API來創建掛起線程,或者提供一個標誌在暫停狀態下創建線程。所以這是一個很好的方法,否則在創建另一個線程時你會失去當前的線程。此外,由於使用輕量級線程,您幾乎被迫創建沒有任何標誌的線程,以便能夠從主線程創建多個線程。

+0

第5步之後,線程實際返回計劃!因爲我保留創建的線程的** UC-link **指向計劃函數(我已經在我的問題中提到過)...一旦你看到那個... – nitish712

+0

@ nitish712我明白了,但它似乎不是回去。你嘗試在'setcontext()'行之後添加一些打印或者調試它嗎?所以我們可以確定它達到了這一點。 – xaizek

+0

是的,你是對的!該線程沒有返回到調用函數。我懷疑調度的上下文已經被執行(調度函數),因此它沒有返回...但至少應該在ryt之後打印什麼?爲什麼沒有發生? – nitish712