The task: to read the files in parallel, output the file name and number from the file to the console, and at the end display the sum of the numbers from the files.

Code:

#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <vector> #include <boost\filesystem.hpp> #include <boost\filesystem\fstream.hpp> #include <boost\thread\thread.hpp> #include <mutex> using namespace std; namespace fs = boost::filesystem; vector<int> values; FILE* txt; fs::path path("c:\\text"); std::vector<boost::thread> threads; std::mutex m; int result = 0; void readFile(fs::directory_iterator it) { fs::ifstream ifs(*it); if (ifs.is_open()) { { std::lock_guard<std::mutex> lock(m); int val; ifs >> val; result += val; cout << it->path().filename() << ": " << val << endl; } ifs.close(); boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); } else { cerr << "Ошибка!" << endl; } } int main() { setlocale(LC_ALL, "rus"); cout << "Введите путь к файлам (*.txt) (например C:\\text): "; cin >> path; cout << endl; for (fs::directory_iterator it(path); it != fs::directory_iterator(); ++it) { if (it->path().extension() == ".txt") { threads.push_back(boost::thread(readFile, it)); } } boost::this_thread::sleep(boost::posix_time::milliseconds(1000)); cout << "Сумма всех чисел: " << result << endl; system("pause"); return 0; } 

In the files (1.txt, 2.txt, 3.txt ...) the numbers are 1, 10, 100, 1000, etc. 1111111 should be at the end, but now the result is enter image description here

What is wrong and how to fix it?

  • Do you have exactly the first files 1, 10 and 100? Did you check from? - Harry
  • And make int val; ifs >> val; int val; ifs >> val; before locking the mutex, otherwise you have a small parallelism - and that one is lost ... - Harry
  • Yes, there are exact numbers in the files. - Vitali
  • And the screen shows that some names are duplicated, but the meanings are different - Vitali
  • one
    In addition, I would advise to pass to the readFile function just the path to the file by value, not the directory_iterator object - Unick

1 answer 1

Apparently the problem is the race between the main stream and the threads for reading files. The fs :: directory_iterator object it has time to change while threads 1, 2 start working. Therefore, it is worth passing the path to the function of threads by value. The code will look something like this:

 .... void readFile(fs::path filePath) { .... } ... if (it->path().extension() == ".txt") { threads.push_back(boost::thread(readFile, it->path())); }