std::queue 不保留数据
std::queue does not keep data
这是我的两个类:
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;
}
所以,我的问题是每次调用函数 Holder::Push q.size() 在开始时等于 0,在函数结束时等于 1。推送的对象就消失了,但我没有调用 q.pop()。
我认为这是你的问题:
th_list.push_back(std::thread(&App::th_getInfo, *this, *it, readFile(holder["cmdFile"])));
std::thread 按值获取参数;所以 *this 创建了一个 App 对象的副本,带有一个单独的 Holder。你可以通过像这样包装来获得引用语义,正如你和上帝所希望的那样:
th_list.push_back(std::thread(&App::th_getInfo, std::ref(*this), *it, readFile(holder["cmdFile"])));
见here类似问题;在您的应用程序的复制构造函数中放置一个调试打印,您应该会在每次创建线程时看到它被调用。
这是我的两个类:
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;
}
所以,我的问题是每次调用函数 Holder::Push q.size() 在开始时等于 0,在函数结束时等于 1。推送的对象就消失了,但我没有调用 q.pop()。
我认为这是你的问题:
th_list.push_back(std::thread(&App::th_getInfo, *this, *it, readFile(holder["cmdFile"])));
std::thread 按值获取参数;所以 *this 创建了一个 App 对象的副本,带有一个单独的 Holder。你可以通过像这样包装来获得引用语义,正如你和上帝所希望的那样:
th_list.push_back(std::thread(&App::th_getInfo, std::ref(*this), *it, readFile(holder["cmdFile"])));
见here类似问题;在您的应用程序的复制构造函数中放置一个调试打印,您应该会在每次创建线程时看到它被调用。