2012-03-12 176 views
4

我创建在C++以下优先级队列优先队列C++

priority_queue < ThreadInfo*, vector<ThreadInfo*>, CompareThread > thread_queue; 

其中的ThreadInfo类是

class ThreadInfo { 
public: 
    ThreadInfo(); 
    ThreadInfo(const ThreadInfo& orig); 
    ThreadInfo(int thread_id,int init_time,int sleep_time,int run_time,int priority,int is_critical) 
    { 
     this->thread_id=thread_id; 
     this->is_critical=is_critical; 
     this->init_time=init_time; 
     this->priority=priority; 
     this->run_time=run_time; 
     this->sleep_time=sleep_time; 
    } 

    void set_critical(bool value) 
    { 
     is_critical=value; 
    } 
    bool get_critical() 
    { 
     return is_critical; 
    } 
    void set_sleep_time(long value) 
    { 
     sleep_time=value; 
    } 

    long get_sleep_time(long value) 
    { 
     return sleep_time; 
    } 

    void set_run_time(long value) 
    { 
     sleep_time=value; 
    } 

    long get_run_time(long value) 
    { 
     return sleep_time; 
    } 
    int get_lock_type() 
    { 
     return lock_type; 
    } 
    void set_lock_type(int lock_type) 
    { 
     this->lock_type=lock_type; 
    } 

    int get_priority() 
    { 
     return priority; 
    } 
    void set_priority(int value) 
    { 
     this->priority=value; 
    } 

    unsigned long int get_thread_id() 
    { 
     return thread_id; 
    } 
    void set_thread_id(unsigned long int value) 
    { 
     this->thread_id=value; 
    } 
    virtual ~ThreadInfo(); 

private: 
    unsigned long int thread_id; 
    long init_time; 
    long sleep_time; 
    long run_time; 
    int priority; 
    bool is_critical; 
    //1=spin,2=busy,3=semaphore 
    int lock_type; 



}; 

和比较类是

class CompareThread { 
public: 
    bool operator()(ThreadInfo* th1, ThreadInfo* th2) 
    { 
     if (th1->get_priority()>th2->get_priority()) return true; 

     return false; 
    } 
}; 

然后我在插入元件下面的函数,

void ThreadScheduler::register_thread(ThreadInfo &th) 
{ 

     thread_queue.push(&th); 


} 

我打电话从下面的函数线程寄存器,

int ThreadController::thread_register(pthread_t &t, int priority, bool critical) 
{ 
    ThreadInfo ti; 
    cout<<"t reg:"<<t<<endl; 
    ti.set_thread_id(t); 
    ti.set_critical(critical); 
    ti.set_priority(priority); 
    ThreadScheduler::Instance()->register_thread(ti); 
} 

但每次当我推一些的ThreadInfo对象到队列我得到的最新的对象时,我打电话thread_queue.top(时间),无论是它应该返回最低优先级的线程对象。这里有什么问题吗?

+2

去你能告诉你把输入到队列中的代码? – 2012-03-12 12:47:38

+0

嗨我更新了代码。在这里你可以看到我是如何推动元素。@ JoachimPileborg – 2012-03-12 12:50:45

+0

你贴了很多* *的代码,*大部分*它无关.. – 2012-03-12 12:51:03

回答

3

您指针传递到相同的内存块放入队列。您正在调用register_thread,并引用本地对象并将其地址排队。这就是他们都一样的原因。另一个问题是,当你离开thread_register函数中的局部ti将被删除(超出范围),你将不得不在队列中没有有效的条目。

你需要做的是为每个信息分配新的内存和数据复制到该内存。因此,每个单元指针插入到队列中有来自不同new,如果你有一个拷贝构造函数,这将做到:

void ThreadScheduler::register_thread(ThreadInfo &th) 
{ 
     thread_queue.push(new ThreadInfo(th)); 
     /* ... */ 
} 

检查:https://stackoverflow.com/a/986093/390913

+0

对不起,我不明白,你可以详细说“这听起来像你正在传递一个指向同一个内存块的指针进入队列”? – 2012-03-12 12:47:10

+0

嗨我更新了代码。 – 2012-03-12 12:51:11

+0

您可以通过从队列中弹出并检查获取的元素来验证此情况。 – 2012-03-12 12:55:03

1

的问题是,你是使用指向在函数中本地声明的变量的指针。只要函数(ThreadController::thread_register)完成,局部变量不再存在,指针现在指向一些未分配的内存。

有两个解决办法:

  1. 使用智能指针,像std::shared_ptr,并在ThreadController::thread_register创建一个新的指针:

    std::shared_ptr<ThreadInfo> ti(new ThreadInfo); 
    

    当然,你必须记住改为std::shared_ptr还有其他地方,并且使用->接入运营商而不是.

  2. 根本不使用指针,并让该类别的数据(这是相当小和简单的)进行复制。

我建议用替代2.

+0

起初我没有在队列中只用线程对象的指针。然后,当我尝试打印队列内容时,它给了我垃圾值。现在没关系,只是内部比较不起作用。 – 2012-03-12 13:04:02

+0

@Pbasak相信我,使用指向局部变量的指针会使程序迟早在你的脸上(象征性地说)爆炸。我的猜测是,纯运气对ThreadController :: thread_register的每次调用都会使结构占据完全相同的内存区域,这意味着它将“覆盖”旧数据。 – 2012-03-12 13:10:01

+0

是的,我想出了问题。相同的数据在每个推送呼叫中被覆盖。所以,同一个线程信息对象被多次推送。 – 2012-03-12 16:19:25