Выполнение кода C ++ для нескольких (~ 9k) файлов отдельно в go - PullRequest
0 голосов
/ 25 марта 2020

Я думаю, что код не имеет отношения к вопросу, поэтому, если вы считаете, что это необходимо в любой момент времени, пожалуйста, укажите. Я могу легко поделиться фрагментами.

Я написал код для проекта, который использует 3 файла:

  1. Входной файл ( .pdb )
  2. Temporary Intermediate (скажем, xyz.txt )
  3. Вывод ( .txt )

Для каждого входного файла программа создает отдельный выходной файл. Кроме того, он использует временный промежуточный файл xyz.txt для процесса. xyz.txt может быть одинаковым для всех файлов. Но проблема в том, что я хочу запустить код для примерно 9000 файлов, и было бы смешно делать это индивидуально для каждого файла.

Можно ли как-нибудь одновременно выполнить эту задачу? Мой код запрашивает местоположение ввода, xyz и выходного файла. Временно я создал файл output.txt , в котором я сохраняю вывод.

cout << "Enter the absolute path to the input file:";
cin >> inputf;
fin.open(inputf);
if ( fin.fail() ) {
    cerr << "Could not open .pdb file " << inputf << endl;
    exit(1);
    }

cout << "Enter the absolute path to a intermediate file (say xyz):";
cin >> xyz;
fout.open(xyz);
if ( fout.fail() ) {
    cerr << "Could not open xyz file " << xyz << endl;
    exit(1);
    }

// some irrelevant code goes here

cout << "Enter the absolute path to the final output file:";
cin >> inputf;
fout.open(inputf);
if ( fout.fail() ) {
    cerr << "Could not open output file " << inputf << endl;
    exit(1);
    }

Я хочу, чтобы имя выходного файла совпадало с именем входного файла. (скажем) Входной файл example.pdb , тогда выходной файл должен иметь имя example.txt .

Заранее спасибо!

1 Ответ

0 голосов
/ 25 марта 2020

Вам нужно выполнить параллельную обработку, а затем последовательно записать на диск (поскольку вы можете только последовательно обращаться к диску). Вы также можете избавиться от временных файлов и обрабатывать большие файлы в чанках. Любая обработка, которую вы выполняете в файле временных данных, может быть заменена чем-то (например, классом), который записывает изменения и применяет их к выходному потоку.

Запись на диск может выполняться с использованием класса буфера / синхронизации, экземпляр которого передается между потоками и который записывает каждое изменение на диск полностью перед обработкой следующего. Это самый чистый способ сделать это, и, хотя, возможно, нет необходимости избегать гонки данных (поскольку вы читаете только из входных файлов и записываете только один вывод на поток), это сделает ваш проект более понятным и обеспечит возможность расширения в будущем ( также предотвращает разброс файла в случае жестких дисков). Asio - это библиотека, предназначенная для асинхронного ввода-вывода и оснащенная пулами потоков, асинхронной обработкой файлов и многими другими полезными вещами, что означает, что вам (в основном) не нужно беспокоиться о том, что я сказал выше.

Однако, если вы не выполняете какую-то очень сложную вычислительную задачу, диск все равно будет вашим узким местом. Опять же, в зависимости от сложности обработки ваших программ, это решение может принести только минимальное усиление.

В качестве примечания вы можете вычислить имя выходного файла из имени входного файла, используя stem() метод std::filesystem::path. Как это:

std::filesystem::path my_path("foo.txt");
std::filesystem::path my_output_path(my_path.stem()+std::filesystem::path(".my_extension"));
...