Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Запуск метода в отдельном потоке


Автор: batex 6.8.2012, 12:35
Добрый день. Есть класс MainClass. Необходимо из одного метода этого класса запустить другой в другом потоке. Метод нельзя делать статиком. Необходимо оставить все вкусности ООП.
Т.е.

Код

class MainClass{
typedef MainClass this_t;
//тут много всяких методов.
static void Method1(this_t* this1, int stat, size_t writ)
{
bool success = (stat == 0 && writ != 0);
this->Method2(success);//вот этот метод отсюда необходимо запустить в другом потоке.
}
void Method2(bool success)
{
тут что-то долго происходит...
}
//еще много всякого


Гугл пока что не очень помог. Есть какие нибудь идеи?

Автор: saneea 6.8.2012, 13:31
Ну на чистом C++ никак такое не сделать. Нужно использовать WinAPI (ну или Qt, boost как обёртки).

Автор: boostcoder 6.8.2012, 13:38
http://liveworkspace.org/code/5e1eab966cb443ba57b8d2f1e5693b22:
Код

#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <boost/noncopyable.hpp>
#include <boost/shared_ptr.hpp>

namespace ba = boost::asio;

template<typename T>
struct threaded_object: boost::noncopyable {
   threaded_object()
   :_ios(),
   _work(new ba::io_service::work(_ios)),
   _thread(boost::bind(&ba::io_service::run, &_ios)),
   _obj()
   {}
   
   ~threaded_object() {
      _work.reset();
      _thread.join();
   }

   template<typename... Args>
   void operator()(void(T::*m)(Args...), Args... args) {
      _ios.post(boost::bind(m, &_obj, boost::cref(args)...));
   }
   
private:
   ba::io_service _ios;
   boost::shared_ptr<ba::io_service::work> _work;
   boost::thread _thread;
   T _obj;
};

struct test {
   void m1() {
      std::cout
      << "this thread id = " << boost::this_thread::get_id() << " -> "
      << __PRETTY_FUNCTION__ << std::endl;
   }
   void m2(int v) {
      std::cout
      << "this thread id = " << boost::this_thread::get_id() << " -> "
      << __PRETTY_FUNCTION__ << ": v = " << v << std::endl;
   }
   void m3(int v, const char* s) {
      std::cout
      << "this thread id = " << boost::this_thread::get_id() << " -> "
      << __PRETTY_FUNCTION__ << ": v = " << v << ", s = " << s << std::endl;
   }
};

int main() {

   std::cout << "main thread id = " << boost::this_thread::get_id() << std::endl;
   threaded_object<test> t;
   t(&test::m1);
   t(&test::m2, 33);
   t(&test::m3, 44, "55");
}


Добавлено @ 13:39
Цитата(saneea @  6.8.2012,  13:31 Найти цитируемый пост)
на чистом C++ никак такое не сделать.

легко.
std::list+std::thread+std::bind

Автор: EnergoHokum 6.8.2012, 13:54
http://rsdn.ru/Forum/Info/FAQ.cpp.threadandmember.aspx.

Автор: saneea 6.8.2012, 16:02
Цитата

легко.
std::list+std::thread+std::bind

спасибо, буду знать, что новый стандарт C++ знает, что такое потоки!  smile 

Автор: borisbn 7.8.2012, 09:27
Цитата(boostcoder @  6.8.2012,  13:38 Найти цитируемый пост)
std::list+std::thread+std::bind

не очень понял, зачем в данном случае нужен list  smile 
Вот самое простое, что можно сделать для задачи ТС

Код

class MainClass {
public:
    MainClass() : m_thread( 0 ) {}
    ~MainClass() {
        if ( m_thread ) {
           m_thread->join();
        }
    }
//тут много всяких методов.
   void Method1( int stat, size_t writ )
   {
      bool success = (stat == 0 && writ != 0);
      m_thread = new std::thread( & MainClass::Method2, this, success ); //вот этот метод отсюда необходимо запустить в другом потоке.
   }
private:
   std::thread * m_thread;
   void Method2( bool success )
   {
      //тут что-то долго происходит...
      cout << this << " " << __PRETTY_FUNCTION__ << " = " << success << endl;
   }
//еще много всякого
};

int main()
{
   MainClass a;
   MainClass b;
   a.Method1( 0, 42 );
   b.Method1( 1, 42 );
}

http://liveworkspace.org/code/8bdc1ded8c79e39e4a0694e20a8375b7

Кста, тут и bind не потребовался

Автор: boostcoder 7.8.2012, 09:50
Цитата(borisbn @  7.8.2012,  09:27 Найти цитируемый пост)
зачем в данном случае нужен list

а есть гарантия что выполнение предыдущего метода завершится раньше чем ты решишь выполнить еще один?

Автор: baldina 7.8.2012, 10:28
Цитата(boostcoder @  7.8.2012,  09:50 Найти цитируемый пост)
а есть гарантия что выполнение предыдущего метода завершится раньше чем ты решишь выполнить еще один?

почему бы им не работать параллельно? последовательным должен быть доступ к членам класса, для этого есть блокировки, но семантику метода определяет разработчик. (хотя по мне лучше вместо обеспечения реентерабельности использовать разные объекты, а синхронизацию возложить на специальный объект. так проще и понятней. но это значит - никаких параллельных запусков функции-члена из самого объекта)

Автор: boostcoder 7.8.2012, 10:41
Цитата(baldina @  7.8.2012,  10:28 Найти цитируемый пост)
почему бы им не работать параллельно?

в каком кол-ве?
почему именно в таком?
чем ограничивается?
интеллектуальный пул?

есть ли вообще в этом смысл?

Автор: baldina 7.8.2012, 13:59
Цитата(boostcoder @  7.8.2012,  10:41 Найти цитируемый пост)
в каком кол-ве?
почему именно в таком?
чем ограничивается?
интеллектуальный пул?

есть ли вообще в этом смысл?

это вопросы к разработчику класса  smile 

хотя абстрактную сферическую задачу сформулировать могу, например - рассылка спама. упомянутая функция берет из базы адрес, куда еще не было рассылки, шлет письмо и обновляет базу. цель - разослать письма всем адресатам из базы. допустим в данных класса только информация о соединении к базе и сам запрос, значит данные класса не модифицируются, так что даже блокировок не надо (это задача базы). вот эту функцию и можно параллелить

Добавлено через 46 секунд
повторюсь, это не мой метод, просто модель ответа на конкретный вопрос))))

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)