需求:最近接到乙個有趣的任務,就是需要快速遍歷目錄裡面的所有目錄以及檔案,並且需要越快越好。
遇到的有趣問題:
1、第一遍讀取時間很慢,第二遍開始讀取時間就很快了,比如2g的檔案第一次執行大概是3500ms,第二次執行**大概500ms左右。
2、多執行緒在開啟4個以後新能就提公升不上去了
執行環境:系統:linux-deepin桌面版 開發工具:qt cpu4核
演算法說明:
第一想到的肯定是遞迴,但是遞迴在效能上面肯定受到影響,所以使用佇列的方式進行遍歷.
我採用的方式是佇列的方式讀取檔案內容。
比如目錄結構如下
先取出第乙個目錄 放入佇列,然後讀取第一佇列的目錄httpd,得到conf,www將這幾個目錄分別放入佇列中,
取出第二個目錄conf,獲取他的子目錄aliyun,baidu,qq將其放入佇列中,
讀取佇列中頭部檔案www,獲取他子目錄163,baidu,weixin
以此類推,等到所有的目錄都進入佇列並且佇列都被讀取完畢那麼所有的檔案就讀取完成了。
原始碼:
第一版本先不使用多執行緒方式,
void dialog::countdir3()
// 定義乙個佇列。
// 邏輯如下:獲取乙個目錄讀取該目錄下的所有目錄,並且將其放入佇列中。
qqueueq;
qfileinfo info(path);
q.enqueue(info);
// 統計檔案數量
int i = 0;
doi++; // 統計檔案和目錄數量
if(finfo.isdir())
}// 如果所有的佇列都被展開完畢說明所有檔案已經讀取完畢
}while(!q.isempty());
qdebug() << "time to count entries and size:" << timer.elapsed() << "ms";
qdebug() 第二版本使用執行緒池方式,
演算法還是一樣的,但是多個執行緒同時讀取佇列的第乙個資料,同時讀取硬碟。
因為佇列只有乙個所有這裡涉及到佇列的公有變數互斥問題,我只是使用了簡單的互斥(應該還有優化空間)
myrunnable.h標頭檔案
#ifndef myrunnable_h
#define myrunnable_h
#include #include#include#include#include#include#include#include#include#include#include#includeextern qqueuetq1;
extern int ti;
extern qmutex tmut;
extern qmutex tp_mut;
extern qmutex tmut_i;
extern qelapsedtimer ttimer;
class myrunnable : public qrunnable
;#endif // myrunnable_h
myrunnable.cpp原始檔
#include "myrunnable.h"
qqueuetq1;
int ti = 0;
qmutex tmut_i;
qmutex tmut;
qmutex tp_mut;
qelapsedtimer ttimer;
myrunnable::myrunnable()
void myrunnable::setqueue(qqueue*m_q)
void myrunnable::setpath(qstring name)
void myrunnable::run()
qfileinfo info(path);
tq1.enqueue(info);
int c = 0;
doti++;
if( finfo.isdir())
}c++;
if(c>10)
}while(!tq1.isempty());
//執行緒池使用。讀取資料
qthreadpool::globalinstance()->setmaxthreadcount(10);
for (int i =0; i< 10;i++ )
qthreadpool::globalinstance()->waitfordone();
qdebug()<
}
有感於濫用多執行緒之遍歷檔案目錄資訊
今天這篇博文,完全是有感而發,不僅僅是經常看到有人求資料夾遍歷的 主要是,看到有些人寫了一些多執行緒讀取的方法,貼到網上供人參考使用,然後真有不少人特意求這種多執行緒遍歷檔案目錄的方法。看到這個現象,我很無奈。真的。為什麼這麼說,因為了解傳統硬碟工作原理的人,稍微想想,就應該明白,讀取某個資料夾下的...
Linux 迴圈遍歷檔案目錄
作業系統 unbuntu 問題域 在乙個檔案目錄下,巢狀有多個子目錄,需要遍歷這些子目錄,並在子目錄下進行相關操作,譬如 批量重新命名,目錄下的檔案 又或者需要,設定工程目錄 mvn versions set dnewversion 1.12 等等。解決辦法 for dic in doif test...
linux下遍歷目錄和檔案
目錄操作相關函式 1 opendir 開啟目錄 dir opendir const char name 引數 要開啟的目錄名 返回值 指向目錄的指標 這裡的dir型別可以int dirfd dir dirp 函式轉變為描述符 fd 2 讀目錄 readdir struct dirent readdi...