我试图从Linux中的文件夹中读取所有文件和目录,其线程为 获取最大文件大小&当前目录和当前目录树下的名称。在线程应用程序(linux,pthreads)中读取文件大小时出错
主线程扫描基本目录查找文件,当找到它的目录时,会生成一个新线程以生成继续扫描的线程。
在这一点上,线程加入,直到最后创建的线程结束。 (我知道这不是最好的方法,但它只是一个练习。)
问题是,它的程序返回错误的结果,我不知道为什么。
我有以下文件树来测试应用程序:下树
. (Debug folder under codelite project/workspace)
├── [ 4096] dir1
│ └── [ 9] arch-dir1.txt
├── [ 4096] dir2
│ ├── [ 27] arch-dir2.txt
│ └── [ 29083] huge
├── [ 29053] direxp
├── [ 27048] direxp.o
└── [ 68] direxp.o.d
正如你可以看到当前目录下的最大文件大小是direxp(这个节目),最大文件大小是巨大的
运行二进制文件,我得到了以下结果:
dir: .
dir: ..
arch: direxp.o.d
max dir & tree set to: direxp.o.d size: 68
arch: direxp.o
max file dir set to: direxp.o size: 27048
arch: .d
arch: direxp
max file dir set to: direxp size: 29053
dir: dir1
th dir: .
th dir: ..
th arch: arch-dir1.txt thsize: 4096
max tree file set to: arch-dir1.txt thsize: 4096
dir: dir2
th dir: .
th dir: ..
th arch: arch-dir2.txt thsize: 4096
th arch: huge thsize: 4096
Highest current directory file:
direxp tam:29053 bytes.
Highest tree file:
arch-dir1.txt tam:4096 bytes.
个前缀字符串显示在另一个线程处理的数据。
我使用函数readdir(主线程)和readdir_r(衍生线程)来读取目录条目。
我认为这可能是麻烦,但后来编译程序调用readdir_r在所有线程下,并且错误的结果仍然存在。
我真的不明白,为什么文件大小它返回错误的(4096它在我的文件系统默认的簇大小。那么,为什么文件处理为目录?
能给我一个忙吗? 感谢
主要功能码
#include
#include
#include
#include
#include
#include
#include
#include
#include
using std::cout;
using std::cin;
using std::endl;
#define MAX_PATH 255
struct archivo
{
char nombre[MAX_PATH+1];
off_t tam;
};
// thread args
struct thargs
{
char nextdir[MAX_PATH+1]; // next dir
void* (*pth)(void*); // pointer to thread function
archivo* arch; // pointer to archivo
};
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
int main(int argc, char **argv)
{
char target[MAX_PATH+1] = {0}; // directorio inicial
archivo grande_dir ={{0}},grande_arbol = {{0}};
// No params
if (argc < 2)
{
if (! getcwd(target,MAX_PATH))
{
perror("Error en path:");
exit(-1);
}
}
if (argc == 2)
strncpy(target,argv[1],MAX_PATH);
if (argc > 2)
{
perror("Num params incorrecto");
exit(-2);
}
DIR* midir = NULL;
// try to open target dir
if (! (midir = opendir(target)))
{
perror("Error abriendo dir:");
exit(-3);
}
dirent* direntry;
//dirent* rentry1 = NULL;
struct stat estado = {0}; // struct needed for desambiguation
bool primera = true; // control var to initialize the search
// read current dir contents
//while((readdir_r(midir,&direntry,&rentry1) == 0) && rentry1 )
while((direntry = readdir(midir)))
{
stat(direntry->d_name,&estado);
// current entry it's a file
if (direntry->d_type == DT_REG)
{
cout << "arch: " << direntry->d_name << endl;
// init search to find the highest file
if (primera)
{
strncpy(grande_dir.nombre,direntry->d_name,MAX_PATH);
grande_dir.tam = estado.st_size;
strncpy(grande_arbol.nombre,direntry->d_name,MAX_PATH);
grande_arbol.tam = estado.st_size;
primera = false;
cout << "max dir & tree set to: " << direntry->d_name << " size: " << estado.st_size << endl;
}
// High file size
if (estado.st_size > grande_dir.tam)
{
pthread_mutex_lock(&lock);
strncpy(grande_dir.nombre,direntry->d_name,MAX_PATH);
grande_dir.tam = estado.st_size;
pthread_mutex_unlock(&lock);
cout << "max file dir set to: " << direntry->d_name << " size: " << estado.st_size << endl;
}
}
// current entry it's a directory
if (direntry->d_type == DT_DIR)
{
cout << "dir: " << direntry->d_name << endl;
// check not . or .. dir
if ((strcmp(direntry->d_name,".") != 0) && (strcmp(direntry->d_name,"..") != 0))
{
thargs args = {{0}};
pthread_t th1;
pthread_mutex_lock(&lock);
sprintf(args.nextdir,"%s/%s",target,direntry->d_name);
args.arch = &grande_arbol;
args.pth = &procesadir;
pthread_mutex_unlock(&lock);
// new thread creation
pthread_create(&th1,NULL,procesadir,&args);
// main thread waits th1 completion
pthread_join(th1, NULL);
}
}
}
closedir(midir);
pthread_mutex_destroy(&lock);
cout << endl << "Highest file in current directory file :" << endl
<< grande_dir.nombre << " tam:" << grande_dir.tam
<< " bytes." << endl;
cout << endl << "Highest file in tree:" << endl
<< grande_arbol.nombre << " tam:" << grande_arbol.tam
<< " bytes." << endl;
return 0;
}
线程函数代码
void* procesadir(void* args)
{
thargs* myargs = reinterpret_cast(args);
DIR* thdir = NULL;
if ((thdir = opendir(myargs->nextdir)))
{
dirent thentry;
dirent* rentry = NULL;
struct stat thstat = {0};
//while((thentry = readdir(thdir)))
while((readdir_r(thdir,&thentry,&rentry) == 0) && rentry )
{
stat(thentry.d_name,&thstat);
if (thentry.d_type == DT_REG)
{
cout << " th arch: " << thentry.d_name << " thsize: " << thstat.st_size << endl;
if (thstat.st_size > myargs->arch->tam)
{
pthread_mutex_lock(&lock);
memset(myargs->arch->nombre,0,MAX_PATH);
strncpy(myargs->arch->nombre,thentry.d_name,MAX_PATH);
myargs->arch->tam = thstat.st_size;
pthread_mutex_unlock(&lock);
cout << "max tree file set to: " << thentry.d_name << " thsize: " << thstat.st_size << endl;
}
}
if (thentry.d_type == DT_DIR)
{
if ((strcmp(thentry.d_name,".") != 0) && (strcmp(thentry.d_name,"..") != 0))
{
thargs largs = {{0}};
pthread_t th2;
sprintf(largs.nextdir,"%s/%s",myargs->nextdir,thentry.d_name);
largs.arch = myargs->arch;
largs.pth = myargs->pth;
// thread creation
pthread_create(&th2,NULL,procesadir,&args);
// current thread waits th2 completion
pthread_join(th2, NULL);
}
cout << " th dir: " << thentry.d_name << endl;
}
}
closedir(thdir);
else
perror("Error abriendo dir en thread:");
return 0;
}
2012-01-26
ppk