Проблема с удалением данных thread_specific_ptr в конце потока

Я использую поток локального хранилища с boost. У меня есть глобальная переменная:

boost::thread_specific_ptr<MyDataClass> p_timeline_ctx;

и у меня есть следующий класс, который инкапсулирует объект boost::thread и содержит дополнительный объект данных:

class MyThread {
   private :
      boost::thread t;
      MyDataClass d;

   public :
      MyThread():c() {}

      void start(void) {
         ptr.reset(this->d);
         this->t = boost::thread(&MyThread::worker, this);
      }

      void worker(void) {
         // do something
      }

};

Я не получаю никакой ошибки при компиляции. Но во время выполнения, когда рабочая функция завершается и поток завершается, я получаю ошибку "glibc ... free ... invalid pointer".

Я предполагаю, что это происходит из-за того, что, согласно документу Boost, thread_specific_ptr пытается удалить объект, на который он указывает, когда заканчиваются потоки. Но я не вижу, как решить проблему.

1 ответ

Решение

Указатель конкретного потока становится владельцем. Вы можете сбросить его:

p_timeline_ctx.reset(0);

или, во-первых, инициализируйте его глубокой копией:

ptr.reset(new MyDataStruct(d));

Тем не менее, вам было бы гораздо лучше просто передать ссылку в качестве аргумента указателю потока.

На самом деле, работник уже является функцией-членом экземпляра, поэтому зачем вам нужна специфичная для потока копия этого:

#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include <iostream>

struct MyDataClass { };

class MyThread {
    private :
        boost::thread t;
        MyDataClass d;

    public :
        MyThread(): d() {}

        void start(void) {
            t = boost::thread(&MyThread::worker, this);
        }

        void worker() {
            // just use this->d here
        }
};

int main()
{
}

Или используя функцию статического потока:

#include <boost/bind.hpp>
#include <boost/thread.hpp>

#include <iostream>

struct MyDataClass { };

class MyThread {
    private :
        boost::thread t;
        MyDataClass d;

    public :
        MyThread(): d() {}

        void start(void) {
            t = boost::thread(&MyThread::worker, boost::ref(d));
        }

        static void worker(MyDataClass&) {
            // do something
        }
};

int main()
{
}
Другие вопросы по тегам