【问题标题】:Priority Queue C++优先队列 C++
【发布时间】:2012-03-28 20:39:24
【问题描述】:

我在 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);
}

但是每次当我将一些线程信息对象推送到队列时,当我调用 thread_queue.top() 时,我都会得到最新的对象,它是否应该返回具有最低优先级的线程对象。这里有什么问题吗?

【问题讨论】:

  • 您能显示将条目放入队列的代码吗?
  • 您好,我更新了代码。在这里你可以看到我是如何推送元素的。@JoachimPileborg
  • 您发布了 很多 代码,大部分 不相关..
  • 你能显示你调用 register_thread 的代码吗?
  • ok.. 现在告诉我们你在哪里创建这些 ThreadInfo-s

标签: c++ data-structures queue priority-queue


【解决方案1】:

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

你需要做的是为每个信息分配新的内存并将数据复制到这个内存中。因此,您插入队列的每个元素指针都必须来自不同的new,如果您有一个复制构造函数,则可以这样做:

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

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

【讨论】:

  • 对不起,我不明白。您能否详细说明“听起来您正在将指向同一内存块的指针传递到队列中”?
  • 您可以通过从队列中弹出并检查获取的元素来验证这一点。
  • 嗨,我在这里推送 threadinfo 对象的引用,我还需要复制构造函数吗?
  • @Pbasak,看看你的类,你真的不需要构造函数,默认的就可以了。完成后不要忘记删除新的对象。
  • 嗨,队列内容还可以,但由于某种原因比较不起作用,我想。因为最低的元素不在顶部。
【解决方案2】:

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

有两种解决方案:

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

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

    当然你必须记住在其他地方也改成std::shared_ptr,并且使用-&gt;访问操作符而不是.

  2. 根本不使用指针,让类数据(非常简单)被复制。

我建议使用备选方案 2。

【讨论】:

  • 起初我没有在队列中只使用线程对象中的指针。然后,当我尝试打印队列内容时,它给了我垃圾值。现在没关系,只是内部比较不起作用。
  • @Pbasak 相信我,使用指向局部变量的指针迟早会让程序在你面前炸毁(形象地说)。我的猜测是,每次调用 ThreadController::thread_register 纯属运气,都会使结构占用完全相同的内存区域,这意味着它将“覆盖”旧数据。
  • 是的,我发现了问题所在。每次推送调用都会覆盖相同的数据。所以,相同的线程信息对象被多次推送。
猜你喜欢
  • 2010-12-28
  • 1970-01-01
  • 1970-01-01
  • 2016-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 2017-06-13
相关资源
最近更新 更多