2016-06-29 5 views
1

Мне нужно запустить поток, который вызывает функцию открытого члена класса Foo, находясь внутри публичной функции, принадлежащей классу Bar. Как мне это достичь?Запуск потока от функции-члена в функции члена другого класса

Я попытался следующие (тривиальное):

void Bar::BarFunc() 
{ 
    // Do some BarFunc stuff 

    // Start a thread that needs to do stuff independently of BarFunc 
    std::thread t(&Foo::FooFunc, FooFunc params,..,.., ???); 
    t.detach(); 

    return; 
} 

Это мой первый раз дело с потоками и актуальной проблемой является немного более сложным - BarFunc виртуальная функция государственного класса, с n-конкретные классы, реализующие разные состояния, в которых может существовать мое приложение, следовательно, вопрос. Я не уверен, что поставить в качестве последнего параметра, если угодно. Я посмотрел на this ответ, но не могу определить, какой синтаксис использовать, если какой-либо из них даже применим.

И, наконец, если это плохая практика, я был бы признателен за любые советы по дизайну.

+4

Из-за «Это мой первый раз, когда речь идет о резьбе»: не отсоединяйте нитку! –

+0

@ DieterLücking Как я могу правильно использовать функцию соединения? –

+0

Необходимые параметры зависят от 'Foo :: FooFunc', к которым мы, к сожалению, не привязаны. Я боюсь, что вы, возможно, немного сократили свой пример. Если у вас есть стек разных классов с различными возможными аргументами, вы можете использовать [std :: bind] (http://en.cppreference.com/w/cpp/utility/functional/bind), чтобы предварительно -упаковать функцию с помощью аргументов. – user4581301

ответ

1

Вы, вероятно, придется управлять двумя экземплярами:

  • Экземпляр Foo
  • волоске выполняет функцию-член Foo

Это приводит к следующему эскизу класса Bar:

#include <iostream> 
#include <thread> 

struct Foo{ 
    void print(std::string s) { // by value! 
     std::cout << s; 
    } 
}; 

class Bar{ 
    public: 
    void hello() { 
     // Ensure the thread is not running 
     // (Only one thread is supported in this example) 
     if(! foo_thread.joinable()) { 
      // Move a newly constructed thread to the class member. 
      foo_thread = std::thread(
       &Foo::print,  // pointer to member function of Foo 
       &foo,    // pointer to the instance of Foo 
       "hello\n"   // arguments by value 
      ); 
     } 
    } 

    ~Bar() { 
     // Ensure the thread has been started. 
     if(foo_thread.joinable()) { 
      // This will block until the thread has finished. 
      foo_thread.join(); 
     } 
    } 

    private: 
    Foo foo; 
    std::thread foo_thread; 
}; 

int main() 
{ 
    Bar bar; 
    bar.hello(); 
} 

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

+0

Спасибо. Это помогло мне увидеть лучший способ реализации потока: объект должен существовать только во время жизни потока. Я создам объект и присоединяюсь к потоку, уничтожая объект. –

Смежные вопросы