使用std :: filesystem和多线程搜索文件

问题描述

我编写了一个程序,使用std :: filesystem在系统上按名称搜索文件(使用std :: filesystem :: recursive_directory_iterator进行递归搜索)。如果我从Linux的根目录(“ /”)开始,则仅使用一个主线程,执行时间约为1秒,即可正常工作。 问题:当我尝试使用多个线程运行该程序时,我异常中止(核心转储),并且文件系统错误:递归目录迭代器无法打开目录:不是目录。我要运行该功能

bool SearchFile::find_file_in_directory(const std::string file_name,fs::path path) 
同时在8个线程中使用

,但是具有不同的参数(路径参数将是另一个)。 我试图通过这种方式实现多线程: 计算系统上所有现有文件数量,然后将该数量除以线程数量,并指定每个线程入口目录以开始搜索。 我也有自己的类,用于处理名为SearchFile(sf)的文件。 下面列出的代码

首先是一个线程的方法(它可以根据需要工作):

bool SearchFile::find_file_from_directory(const std::string file_name,fs::path path) {
  if (fs::is_directory(path))
    for (auto &p : fs::recursive_directory_iterator(
             path,fs::directory_options::skip_permission_denied)) {
      path = p;
      if (path.filename() == file_name) {
        curr_path = path;
        return true;
      } else {
        // uncomment this line to see how the function search file
        // std::cout<<path<<"\n";
        continue;
      }
    }
  else
    std::cout << "Entered path is not a directory\n";

  return false;

  std::cout << "File doesn`t exist\n";
  return false;
}

我使用的SearchFile方法

bool SearchFile::find_file_in_directory(const std::string file_name,fs::path path) {
  if (fs::is_directory(path))
    path /= file_name;
  if (fs::exists(path)) {
    return true;
  } else
    std::cout << "Entered path is not a directory\n";
  return false;

  std::cout << "File doesn`t exist\n";
  return false;
}

u_int SearchFile::get_num_of_files_recursively(const fs::path path) {
  u_int num = 0;
  if (fs::is_directory(path)) {
    for (fs::recursive_directory_iterator it(
             path,fs::directory_options::skip_permission_denied);
         it != fs::recursive_directory_iterator(); ++it) {
      num++;
    }
  } else {
    std::cout << "Entered path is not a directory\n";
    return 0;
  }
  return num;
}

main.cpp

#include <iostream>
#include <string>
#include <thread>
//#include "library/searchfile.h"
#include <condition_variable>
#include <fstream>
#include <vector>
//#pragma once
#include <filesystem>

SearchFile sf;
std::condition_variable cv;
std::vector<fs::path> arr;

void do_division(const fs::path path,const u_int times) {
  u_int files_num = sf.get_num_of_files_recursively(path),part = files_num / times;
  u_int i = 0;
  arr.push_back(path);
  for (fs::recursive_directory_iterator it(path,fs::directory_options::skip_permission_denied);
       it != fs::recursive_directory_iterator(); ++it) {
    if (i == part) {
      arr.push_back(it->path());
      part += part;
    }
    i++;
  }
}

void do_job(const fs::path path,const std::string name) noexcept {
  for (auto &p : fs::recursive_directory_iterator(path,fs::directory_options::skip_permission_denied)) {
    std::cout << std::this_thread::get_id() << " - " << p.path() << "\n";

    if (sf.find_file_in_directory(name,p.path())) {
      cv.notify_all();
      std::fstream f;
      std::string path = p.path().string();
      f.open(path);
      f << path;
      f.close();
      return;
    }
  }
}

int main() {
  std::string filename = "MyFile.txt";
  std::string path = "/";

  do_division("/",8);

  while (1) {
    std::thread t1(do_job,arr[0],filename);
    t1.detach();

    std::thread t2(do_job,arr[1],filename);
    t2.detach();

    std::thread t3(do_job,arr[2],filename);
    t3.detach();

    std::thread t4(do_job,arr[3],filename);
    t4.detach();

    std::thread t5(do_job,arr[4],filename);
    t5.detach();

    std::thread t6(do_job,arr[5],filename);
    t6.detach();

    std::thread t7(do_job,arr[6],filename);
    t7.detach();

    std::thread t8(do_job,arr[7],filename);
    t8.detach();
  }
  return 0;
}

也许这不是解决我的问题的好方法,但我只是一个初学者。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)