#cpp #многопоточность
Здравствуйте, недавно пришлось заняться разработкой многопоточного приложения (впервые) и наткнулся на такую проблему: позарез нужно создать поток для конкретного объекта с передачей в конструктор имени нестатической функции, гугл ничего путного не дал. Подскажите, это вообще возможно? Если нет, то как это 'лечиться'? В абстракции: есть класс System, у него есть нестатический метод private update() который я должен отслеживать, путем инициализации указателя private thread* Thread в конструкторе класса. P.S в update вызывается метод move(...), который привязан к объекту, т.е я не могу сделать update статическим без создания контейнера, хранящего все данные о пользователях, а это затратно #include//еще включения ... class System { //некоторые поля и методы... //... thread* Thread; static thread* sThread; System() { Thread = new thread(update);//ошибка! отсутствуют экземпляры констуктора соответствующий ... для std::thread::thread (void()) } void update() { //... move(...); //... } void move() { //работает с полями объекта } }; { //где-то создается System* system = System; } P.S(2) Перелез с c#, там можно инициализировать потоки нестатическими методами(вроде), не судите строго
Ответы
Ответ 1
В документации говорится, что конструктор выглядит так: template< class Function, class... Args > explicit thread( Function&& f, Args&&... args ); поэтому могу предположить, что следует использовать лямбда-функцию как-то так: new thread([&]() { this.update(); }) В любом случае следует быть осторожным со временем жизни объектов.Ответ 2
Также возможен вариант с использованием std::bind System() { Thread = new std::thread(std::bind(&System::update, this)); }Ответ 3
Я абсолютно не уверен в том, что это хорошая идея, но используя лямбду вместо update и дополнительно дав компилятору опцию -pthread мне удалось запустить, и даже получить результат следующего кода: class System { //некоторые поля и методы... //... static thread* sThread; public: thread* Thread; System() { Thread = new thread([this]{ /*Это код метода update, который вызывает move, лямбда должна захватить указатель на текущий объект чтоб вызвать функцию объекта */ cout << "Updte\n"; this->move(); }); } private: void move() { cout << "Move\n"; } }; int main(){ System s; s.Thread->join(); return 0; } Повторю, что по-моему это все имеет кучу подводных камней, поэтому интересно увидеть ответы более знающих людей.Ответ 4
А зачем сложно, если можно просто? Указать, что это функция-член, и добавить this? #include#include using namespace std; class Test { public: Test(int x):x(x){}; void out(int b) { cout << x << ":" << b << endl; } void run(int j) { thread t = thread(&Test::out,this,j); t.join(); } private: int x; }; int main() { Test t(12); t.run(3); }
Комментариев нет:
Отправить комментарий