c++ - Why only last thread executing? -
i need create console application counts files in folders. each folder executes parallel. directories paths .txt file , put them threads.
i'm using std::thread , boost::filesystem.
it works fine 1 directory, crashes or returns wrong results many. interesting last thread gets correct result, before wrong.
here code:
dirhandler.h
#include <iostream> #include <fstream> #include <string> #include <thread> #include <windows.h> #include <boost/filesystem.hpp> using namespace std; using namespace boost::filesystem; class dirhandler{ public: dirhandler(); void getpaths(ifstream file); void output(); static void run_thread(pair<string, int> * dir, string cur_path, void *args) { dirhandler *prunnable = static_cast<dirhandler*>(args); prunnable->some_counting(dir, cur_path); } private: vector<thread> threads; vector<pair<string, int>> paths; // current directory name , files amount void some_counting(pair<string, int> * dir, string cur_path); void escape(); };
dirhandler.cpp
void dirhandler::getpaths(ifstream file) { // parse pathes , create separate thread each string line; if (file.is_open()) { while (getline(file, line)) { cout << line << endl; // add thread path pair<string, int> dir = make_pair(line, 0); paths.push_back(dir); threads.push_back(thread(&dirhandler::run_thread, &paths.back(), line, this)); } (auto& thr : threads){ thr.join(); } file.close(); } } void dirhandler::some_counting(pair<string, int> * dir, string cur_path){...}
main.cpp
#include <iostream> #include <windows.h> #include "dirhandler.h" int main(int argc, char* argv[]) { dirhandler dirhandler = dirhandler(); dirhandler.getpaths(ifstream("strings.txt")); //ifstream(argv[1]) dirhandler.output(); return 0; }
note : while debugging i've found streams before last have id=0 in end
also i've read problem can caused reference single object. (in case it's vector<pair<string, int>> paths
)
so question how few threads work correctly ?
the problem pointers paths
vector, , if vector resized previous pointers (and iterators) elements in vector become invalid. using invalid pointer leads undefined behavior leads crashes.
and 1 common way of causing vector adding new elements it, in loop.
one solution either pass reference vector , index of element thread (the index not change on reallocation). solution have 2 loops, 1 add elements vector , second create threads.
there other solutions too, not passing pointer thread, instead pass pair by value. solution recommend.
after checking code little, see since use std::thread
don't need static member function wrapper @ all. instead can call non-static actual thread function directly:
threads.emplace_back(&dirhandler::some_counting, this, paths.back(), line);
[note use of this
second argument, change emplace_back
threads
vector]
Comments
Post a Comment