我正在尝试使用First Come First Serve策略设计我自己的线程调度程序,我不确定我将线程置于睡眠状态并将其唤醒的方式是否正确。我正在使用C ++和Pthreads库。
我的想法是:
schedule()
函数,表示应该调度调用线程。通过arrival time
,id
,remaining time
。schedule()
内,创建我自己的Thread
对象,该对象存储特定线程的arrival time
,id
和remaining time
属性(这些属性是我编造了)。 Thread
对象也有自己的条件变量。schedule()
函数时,都会创建一个Thread
对象并将其添加到队列的后面。Thread
对象添加到队列后,调用schedule()
的线程应等待其对应的条件变量。 Thread
对象的条件变量,表明它应该运行。所有其他线程应该等待各自Thread
对象中的条件变量。 示例:Thread
,queue[0]
,queue[1]
,queue[2]
和queue[3]
中存在5个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
对象,并且我不断得到段错误,因为主线程试图发出不存在的条件变量的信号。
我的问题是:这种设计是一种有效的方法,可以将线程置于休眠状态并将其作为调度算法的一部分唤醒它们吗?或者主线程是否总是先执行并尝试发出空队列信号?
答案 0 :(得分:0)
'main'线程只是一个碰巧由OS加载程序而不是用户代码创建的线程。它不以任何方式“特殊”。
一个问题是您正在尝试将线程与睡眠调用同步。这不会很好。
如果你想尝试这个,先用另一种方式发出信号。将condvar传递给工人并在main中等待它。当工作人员将自己插入队列时,它可以发出condvar信号,以便main可以继续。