2014-09-28 99 views
0

我想使用先來先服務策略來設計我自己的線程調度程序,但我不確定是否將線程放入睡眠狀態並喚醒它們up是正確的方法。我正在使用C++和Pthreads庫。線程調度模擬:正確的喚醒方式和睡眠線程

我的想法是這樣的:

  • 主線程實例化一個工作線程。
  • 單獨schedule()函數從工作線程調用,表示調用線程應該被調度。通過arrival time,id,remaining time
  • schedule(),創建自己的Thread對象存儲特定線程的arrival timeidremaining time屬性(這些都是我提出了屬性)。 Thread對象也有其自己的條件變量。
  • 每次調用schedule()函數時,都會創建一個Thread對象並將其添加到隊列的後面。
  • 一旦Thread對象已被添加到隊列中,調用schedule()的線程應等待其相應的條件變量。
  • 然後,應該發信號通知隊列前面的Thread對象的條件變量,表明它應該運行。所有其他線程都應該等待它們各自的Thread對象中的條件變量。

:5 Thread對象queue[0]queue[1]queue[2]queue[3],和queue[4]存在。由queue[0]代表的線程應該正在運行,並且由queue[1],queue[2],queue[3]queue[4]表示的線程應當等待它們各自的條件變量。一旦隊列[0]完成執行,它將從隊列中移除,所有Thread對象將向前移動,並且新的queue[0]將被標記爲運行。如果我現在從新的工作線程中調用schedule(),則應該創建一個新的Thread對象並將其添加到queue[4]。調用線程應等待queue[4]

爲了測試這個設計,我寫了一個例子。我省略了arrival time,idremaining time字段,因爲它們在這一點上並不重要。下面是示例代碼:

#include <iostream> 
#include <string> 
#include <vector> 
#include <pthread.h> 
using namespace std; 

class Thread { 
    public: 
      pthread_cond_t conVar; 
}; 

vector<Thread> queue; 
pthread_mutex_t lock; 

void schedule() { 
    pthread_mutex_lock(&lock); 
    cout << "Thread 1 locks the mutex\n"; 
    queue.push_back(first); 
    pthread_cond_wait(&(queue.back()).conVar,&lock); 
} 

void *worker(void *arg) { 

    Thread first; 
    cout << "Thread 1 adding to queue. Going for the wait...\n"; 

    schedule(); 

    cout << "Got out of the wait. Let's do some work\n"; 

    for(int i = 0; i < 20; i++) 
      cout << i << " "; 

    cout << "\n"; 

    pthread_exit(NULL); 
} 

int main() { 


    vector<Thread> queue; 
    pthread_t a; 

    pthread_create(&a,NULL,worker,NULL); 
    cout << "Sleeping in the main thread for a bit....\n"; 
    sleep(1); 

    cout << "Now let's signal the Thread object in the queue\n"; 

    int result = pthread_mutex_trylock(&lock); 
    if(result != 0) 
      sleep(3); 
    pthread_cond_signal(&(queue.front()).conVar); 
    pthread_mutex_unlock(&lock); 
    pthread_join(a,NULL); 


    return 0; 

} 

我曾嘗試這個示例代碼幾次,主線程總是執行第一和嘗試用信號通知隊列的前面。工作線程永遠不會及時獲取隊列以插入Thread對象,並且我不斷收到段錯誤,因爲主線程嘗試發出一個不存在的條件變量的信號。

我的問題是這樣的:這種設計是一種有效的方法,可以將線程掛起並作爲調度算法的一部分來喚醒它們嗎?或者主線程總是先執行並嘗試發信號通知空隊列?

+0

我只看到一個Thread對象和沒有schedule()方法。注意,因爲線程第一次被分配在worker()的堆棧上,所以在worker退出時會超出範圍 – 2014-09-28 23:40:56

+0

@ KC-NH是的,worker應該是Thread的成員函數,Thread實例應該和operator一起動態分配新的,很多的東西:) – 2014-09-28 23:51:07

+0

你只有一個鎖。該鎖是否保護隊列?在持有全局鎖定時進入等待狀態並不奏效。 – 2014-09-29 13:35:07

回答

0

'主'線程恰好是由OS加載程序而不是用戶代碼創建的線程。這不是什麼特別的。

一個問題是,您正試圖與睡眠呼叫同步線程。這將不會結束。

如果您想嘗試此操作,請先以其他方式發信號。傳遞一個condvar給工作人員並在主要等待它。當工作人員將自己插入隊列時,它可以發信號通知condvar,以便main可以繼續。