我想使用先來先服務策略來設計我自己的線程調度程序,但我不確定是否將線程放入睡眠狀態並喚醒它們up是正確的方法。我正在使用C++和Pthreads庫。線程調度模擬:正確的喚醒方式和睡眠線程
我的想法是這樣的:
- 主線程實例化一個工作線程。
- 單獨
schedule()
函數從工作線程調用,表示調用線程應該被調度。通過arrival time
,id
,remaining time
。 - 在
schedule()
,創建自己的Thread
對象存儲特定線程的arrival time
,id
和remaining 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
,id
和remaining 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
對象,並且我不斷收到段錯誤,因爲主線程嘗試發出一個不存在的條件變量的信號。
我的問題是這樣的:這種設計是一種有效的方法,可以將線程掛起並作爲調度算法的一部分來喚醒它們嗎?或者主線程總是先執行並嘗試發信號通知空隊列?
我只看到一個Thread對象和沒有schedule()方法。注意,因爲線程第一次被分配在worker()的堆棧上,所以在worker退出時會超出範圍 – 2014-09-28 23:40:56
@ KC-NH是的,worker應該是Thread的成員函數,Thread實例應該和operator一起動態分配新的,很多的東西:) – 2014-09-28 23:51:07
你只有一個鎖。該鎖是否保護隊列?在持有全局鎖定時進入等待狀態並不奏效。 – 2014-09-29 13:35:07