Очередь приоритетов C ++ - PullRequest
4 голосов
/ 12 марта 2012

Я создал следующую очередь приоритетов в 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 ]

3 голосов
/ 12 марта 2012

Вы передаете указатель на тот же кусок памяти в очередь.Вы вызываете register_thread со ссылкой на локальный объект и ставите в очередь его адрес.Вот почему они все одинаковы.Другая проблема заключается в том, что при выходе из функции thread_register локальный ti будет удален (вне области), и у вас не будет действительных записей в очереди.

Вам нужно выделить новую память для каждой информации и скопировать данные в эту память.Таким образом, каждый указатель элемента, который вы вставляете в очередь, должен исходить из другого new, если у вас есть конструктор копирования, он будет делать:

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

проверить это: https://stackoverflow.com/a/986093/390913

1 голос
/ 12 марта 2012

Проблема в том, что вы используете указатель на переменную, которая объявлена ​​локально в функции. Как только функция (ThreadController::thread_register) завершена, локальная переменная больше не существует, и указатель теперь указывает на некоторую нераспределенную память.

Для этого есть два решения:

  1. Используйте умные указатели, такие как std::shared_ptr, и создайте новый указатель в ThreadController::thread_register:

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

    Конечно, вы должны помнить, чтобы изменить на std::shared_ptr также везде и использовать оператор доступа -> вместо ..

  2. Не использовать указатели вообще, и пусть данные класса (довольно простые и минимальные) копируются.

Предлагаю перейти с альтернативы 2.

...