多线程文件系统扫描优化

时间:2019-03-20 18:32:14

标签: c++ multithreading optimization

该程序的作用是扫描硬盘驱动器中的所有文件。当主线程用所有文件路径填充队列时,多个工作线程开始对文件进行进一步检查。现在我有以下代码:

Scanner.cpp

for (i in words) console.log(words[i])

Scanner.h

#include "Scanner.h"

Scanner::Scanner() : fsscan_done(false)
{
    num_threads = thread::hardware_concurrency() - 1;
}

void Scanner::ScanFile(fs::path path)
{
    ifstream file(path.c_str());
    if (file.is_open())
    {
        // further inspection
    }
}

void Scanner::ThreadScan()
{
    while (!fsscan_done || !files.empty()) {
        unique_lock<mutex> lock(mtx);
        if (files.empty()) {
            lock.unlock();
            continue;
        }
        fs::path path = files.front();
        files.pop();
        lock.unlock();
        ScanFile(path);
    }
}

void Scanner::Scan()
{    
    vector<thread> thread_pool;
    for (int i = 0; i < num_threads; i++)
        thread_pool.push_back(thread(&Scanner::ThreadScan, this));

    ScanDirectory("C:\\");
    fsscan_done = true;

    for (int i = 0; i < num_threads; i++)
        thread_pool[i].join();
}

void Scanner::ScanDirectory(fs::path directory)
{
    for (const auto & entry : fs::directory_iterator(directory)) {
        if (fs::is_directory(entry.path()))
            ScanDirectory(entry.path());
        else {
            if (!fs::is_regular_file(entry.path())) continue;
            unique_lock<mutex> lock(mtx);
            files.push(entry.path());
        }
    }
}

我觉得这段代码可以进一步优化,我特别不喜欢这部分:

#pragma once
#include <iostream>
#include <filesystem>
#include <fstream>
#include <mutex>
#include <string>
#include <thread>
#include <queue>

using namespace std;
namespace fs = std::experimental::filesystem;

class Scanner
{
private:
    unsigned num_threads;
    mutex mtx;
    queue<fs::path> files;
    bool fsscan_done;
    void ThreadScan();
    void ScanFile(fs::path file);
public:
    Scanner();
    void Scan();
    void ScanDirectory(fs::path directory);
};

因为我要检查文件为空两次。我认为至少应该有更好的方法来做到这一点。我对多线程原理还很陌生,所以我已经在SO和其他站点上四处看看,也许条件变量可以在这里为我提供帮助,但是我不确定在这种情况下如何实现它们。

编辑:

已将互斥锁的直接锁定和解锁更改为使用unique_lock,谢谢François Andrieux

0 个答案:

没有答案
相关问题