-2

These are my two classes:

class App {
public:
  void run(){
    std::vector < std::thread > th_list;
    for(std::vector < Host * > ::iterator it = host_list.begin(); it != host_list.end(); it++){
      th_list.push_back(std::thread(&App::th_getInfo, *this, *it, readFile(holder["cmdFile"])));
    }

    for(std::vector<std::thread>::iterator it = th_list.begin(); it != th_list.end(); it++){
      it->join();
    }
  }
private:
  void th_getInfo(Host * pc, std::string info){
    std::string result;
    if(pc->query(info, &result)){
      holder.Push(pc->getIp(), result);
    }
  }


  std::vector < Host * > host_list;
  Holder holder;
};

class Holder {
public:
  void Push(std::string ip, std::string data){
    _m.lock();
    std::pair <std::string, std::string> tmp(ip, data);
    q.push(tmp);
    std::cout << q.size() << std::endl;
    _m.unlock();
  }
  inline std::string &operator[] (std::string j){ return config[j]; }
private:
  std::map <std::string, std::string> config;
  std::mutex _m;
  std::queue < std::pair < std::string, std::string> > q;
}

So, my problem is that on every call of function Holder::Push q.size() equals 0 at start, and 1 at end of this function. Pushed object just disappears, but i don't call q.pop().

  • 2
    Do you pass `Holder` or `App` by value before pushing? Please reate a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us how you use these classes. Also please tell us how you check that there's no items before and after. – Some programmer dude May 01 '15 at 15:24
  • @JoachimPileborg sorry, i don't understand what you mean saying "pass by value". – user2950818 May 01 '15 at 15:29
  • If you pass an object by value to a function, it is *copied*, and no matter what changes you do to the copy, it's still done to the copy and won't be reflected in the original object. – Some programmer dude May 01 '15 at 15:41
  • Ok, i know that. I don't pass neither `Holder` nor `App` in before. `holder` is filed of class `App`. And `queue q` is its field. – user2950818 May 01 '15 at 15:45

1 Answers1

0

I think this is your problem:

th_list.push_back(std::thread(&App::th_getInfo, *this, *it, readFile(holder["cmdFile"])));

std::thread takes arguments by value; so the *this creates a copy of your App object, with a separate Holder. You can get reference semantics, as you and God intended, by wrapping like so:

th_list.push_back(std::thread(&App::th_getInfo, std::ref(*this), *it, readFile(holder["cmdFile"])));

See here for a similar problem; put a debug print in your App's copy constructor and you should see it being called every time you create a thread.

Community
  • 1
  • 1
Rolf Andreassen
  • 450
  • 1
  • 5
  • 9