【问题标题】:C++ Multi threaded directory scan codeC++多线程目录扫描代码
【发布时间】:2011-01-11 02:13:42
【问题描述】:

我正在寻找如何编写多线程 C++ 代码来扫描目录并获取下面所有文件的列表。我已经写了一个可以做的单线程代码和下面可以做的代码。

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <vector>
#include <string>
#include <iostream>
#include <sys/stat.h> /* for stat() */


using namespace std;
int isDir(string path)
;

/*function... might want it in some class?*/
int getdir (string dir, vector<string> &dirlist, vector<string> &fileList)
{
    DIR *dp;
    struct dirent *dirp, *dirFp ;
    if((dp  = opendir(dir.c_str())) == NULL) {
        cout << "Error(" << errno << ") opening " << dir << endl;
        return errno;
    }

    while ((dirp = readdir(dp)) != NULL) {
        if (strcmp (dirp->d_name, ".") != 0 && strcmp(dirp->d_name, "..") != 0) {
            //dirlist.push_back(string(dirp->d_name));

            string Tmp = dir.c_str()+ string("/") + string(dirp->d_name);
            if(isDir(Tmp)) {
            //if(isDir(string(dir.c_str() + dirp->d_name))) {
                dirlist.push_back(Tmp);
                getdir(Tmp,dirlist,fileList);
            } else {
  //              cout << "Files :"<<dirp->d_name << endl;
                fileList.push_back(string(Tmp));
            }

        }
    }
    closedir(dp);
    return 0;
}

int isDir(string path)
{
    struct stat stat_buf;
    stat( path.c_str(), &stat_buf);
    int is_dir = S_ISDIR( stat_buf.st_mode);
//    cout <<"isDir :Path "<<path.c_str()<<endl;
    return ( is_dir ? 1: 0);
}

int main()
{
    string dir = string("/test1/mfs");
    vector<string> dirlist = vector<string>();
    vector<string> fileList = vector<string>();

    getdir(dir,dirlist,fileList);
#if 0
    for (unsigned int i = 0;i < dirlist.size();i++) {
        cout << "Dir LIst" <<dirlist[i] << endl;
        //string dirF = dir + "/" + dirlist[i];
        //getdir(dirF,fileList);
    }
#endif
    for (unsigned int i = 0; i < fileList.size(); i++)
        cout << "Files :"<<fileList[i]<< endl;
    return 0;
}

现在的问题是它是单线程的,我需要扫描大约 8000 个目录,在这些目录下可以存在文件。所以我不知道该怎么做,因为目录的数量可能会有所不同,因为它是由 N 维矩阵决定的。

在这方面的任何帮助都会很棒。提前致谢。

【问题讨论】:

  • 我不太确定您所指的 N 维矩阵是什么。但要回答您的问题,您最终必须进行并行深度优先搜索。我假设您已经知道如何进行多线程编程;如果没有,那么您需要了解这一点,最好使用 Boost 库,而不仅仅是 POSIX 线程。
  • 基本上使用 N 维矩阵我想说假设我们有一个 20x20x20 矩阵,那么我将有 8000 个需要搜索的目录。所以这个可以根据需求增加。
  • 为了获得良好的性能,无论您为此应用程序定义什么,最终您的硬件(和操作系统)也必须支持这一点。通常 I/O 是多线程应用程序的瓶颈,即使您将工作拆分到不同的线程中,它们也倾向于等待对相同 I/O 的访问,从而限制了您希望实现的任何并行性。
  • 目录扫描总是会受到辅助存储的限制,而不是 CPU 时间。多线程可能会使性能更差,而不是更好。
  • @Billy 好点。仅当目录位​​于不同的磁盘上时,多线程才会有所帮助,例如在高度分布式的文件系统中。 OP 不太可能有这个。

标签: c++ multithreading


【解决方案1】:

boost::filesystem 有directory_iterator 和recursive_directory_iterator,前者会获取一个目录的所有内容但不会递归子目录,后者也会递归子目录。

关于线程安全,您可以锁定一个互斥体,然后将结果复制到 std::vector 或两个向量实例中,一个用于文件,一个用于目录,在这种情况下,您至少会有一个本地快照副本.

此时实际“冻结”文件系统以停止任何修改它的进程不是您通常可以做的事情 - 您可以尝试将其上的文件属性设置为只读,然后稍后将其更改回来,但您首先需要获得许可。

【讨论】:

  • 我不能使用 boost::filesystem 调用,因为当前代码不支持它。所以我只需要处理一些通用的 C++ 数据结构。此外,我将研究您提供的方法,看看我们如何获得良好的性能。 :)
猜你喜欢
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-27
  • 1970-01-01
  • 2014-09-30
  • 2015-01-05
  • 1970-01-01
相关资源
最近更新 更多