The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"обвязка для boost::thread"
Вариант для распечатки  
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"обвязка для boost::thread"  
Сообщение от xhook email(ok) on 28-Сен-07, 14:51 
Здравствуйте!
Я пытаюсь написать некий класс модуля, который по инициализации или по вызову метода run() начинал исполнение в отдельном потоке. При уничтожении объекта поток должен быть воссоединен с материнским. На данный момент я пришел к такой вот реализации (которая собственно не работает, иначе бы я вопросы тут не задавал =) ):

class ThreadedModule
{
    public:
        ThreadedModule() {}
        ~ThreadedModule()
        {
            if (_thrd)
            {
                _thrd->join();
                delete _thrd;
            }
        }

        void run()
        {
            this->code();
            _thrd = new boost::thread(_run(this));
        }
        
        virtual void code()
        {
            std::cout << "hello from ThreadedModule::code()\n";
        }

    private:
        boost::thread *_thrd;
        struct _run
        {
            _run (ThreadedModule *th) : th(th) {}
            void operator()()
            {
                th->code();
            }
            ThreadedModule *th;
        };
};

class MyThreadedModule : public ThreadedModule
{
    public:
        virtual void code() { std::cout << "hello from MyThreadedModule::code()\n"; }
};

int main ()
{
    MyThreadedModule mod;
    mod.run();
}

сей код генерирует следующее:

hello from MyThreadedModule::code()
hello from ThreadedModule::code()

Первая строка как и следовало ожидать выводится в следствие вызова code() из run(). Как видно полиморфизм работает прекрасно.
Вторая же строка выводится уже в выделенном потоке, в который передается струтура _run() с предеданным в нее поинтером на MyThreadedModule закастованным до ThreadedModule. По идее должен вызываться метод класса MyThreadedModule, а на самом деле вызывется метод базового класса.
Может кто знает как разрешть проблему? Мне самому лично не нравится вся эта чехорда со struct _run() ... operator()(). Может все-таки есть какой-нибудь способ получить пойнтер на виртуальный метод (хотя бы небезопасный)

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

 Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "обвязка для boost::thread"  
Сообщение от Мимо проходящий email on 28-Сен-07, 15:17 
Попробуй сделать хотябы один метод code не inline
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

2. "обвязка для boost::thread"  
Сообщение от xhook email(ok) on 28-Сен-07, 15:25 
>Попробуй сделать хотябы один метод code не inline

пробовал, никакого эффекта

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

3. "обвязка для boost::thread"  
Сообщение от sascha on 28-Сен-07, 16:20 
1. смотри boost::bind :
  new boost::thread(boost::bind(&ThreadedModule::run, this);
  так мы отказываемся от использования struct _run
2. для полиморфизма мы должны передавать правильный указатель на класс в нашем случае this ??.
3. join в деструкторе - плохое решение.
Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

4. "обвязка для boost::thread"  
Сообщение от xhook email(ok) on 28-Сен-07, 18:30 
спасибо за совет по поводу bind, что-то я про него забыл. теперь оно выглядит немного стройнее:

class ThreadedModule
{
    public:
        ThreadedModule() {}
        ~ThreadedModule()
        {
            if (_thrd)
            {
                _thrd->join();
                delete _thrd;
            }
        }

        void run()
        {
            std::cout << reinterpret_cast< unsigned int >(this) << '\n';
            this->code();
            _thrd = new boost::thread(boost::bind(&ThreadedModule::_run, this));
        }
        
        
        virtual void code()
        {
            std::cout << "hello from ThreadedModule::code()\n";
        }

    private:
        boost::thread *_thrd;
        static void _run(ThreadedModule *tm)
        {
            std::cout << reinterpret_cast< unsigned int >(tm) << '\n';
            tm->code();
        }

};

вывод:
3215966904
hello from MyThreadedModule::code()
3215966904
hello from ThreadedModule::code()

одна и та же лажа... надо полностью принцип менять. хотя данное поведение сего кода мне кажется полной чушью

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

5. "обвязка для boost::thread"  
Сообщение от sascha on 28-Сен-07, 19:05 
Я уже говорил что this - указатель на базовый класс, а тебе нужен указатель на потомка.

посмотри что выдаст эта функция:

virtual void code()
{
   std::cout << reinterpret_cast< unsigned int >(this) << '\n';
   std::cout << "hello from ThreadedModule::code()\n";
}

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

6. "обвязка для boost::thread"  
Сообщение от xhook email(??) on 29-Сен-07, 00:52 
>Я уже говорил что this - указатель на базовый класс, а тебе
>нужен указатель на потомка.
>
>посмотри что выдаст эта функция:
>
>virtual void code()
>{
>   std::cout << reinterpret_cast< unsigned int >(this) << '\n';
>   std::cout << "hello from ThreadedModule::code()\n";
>}

все тот же пойнтер.

Высказать мнение | Ответить | Правка | Наверх | Cообщить модератору

Архив | Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Оцените тред (1=ужас, 5=супер)? [ 1 | 2 | 3 | 4 | 5 ] [Рекомендовать для помещения в FAQ]




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру