2014-09-28 64 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可以继续。