读取线程应用程序(linux,pthreads)中的文件大小时出错
Error reading file size in threaded application (linux,pthreads)
我正试图用线程从linux中的一个文件夹中读取所有文件和目录获得最高的文件大小&当前目录和当前目录树下的名称。
主线程扫描基本目录查找文件,当找到一个目录时,会生成一个新线程继续扫描。
此时,线程连接,直到最后创建的线程结束。(我知道这不是最好的方法,但这只是一种练习。)
问题是,程序返回了错误的结果,我不知道为什么。
我有以下文件树来测试应用程序:
。(codelite项目/工作区下的调试文件夹)├──[4096]dir1│ └──[9]arch-dir1.txt├──[4096]dir2│ ├──[27]arch-dir2.txt│ └──[29083]巨大├──[29053]目录├──[27048]目录└──[68]直接出口
正如你所看到的,在当前目录下的最高文件大小是direxp(这个程序),在树下的最大文件大小是巨大的
运行二进制文件,我得到以下结果:
目录:。目录:。。拱门:direxp.o.d最大目录树设置为:direxp.o.d大小:68拱门:direxp.o最大文件目录设置为:direxp.o大小:27048拱门:.d拱门:direxp最大文件目录设置为:direxp大小:29053目录:目录1th目录:。th目录:。。th-arch:arch-dir1.txt thsize:4096最大树文件设置为:arch-dir1.txt thsize:4096目录:目录2th目录:。th目录:。。th-arch:arch-dir2.txt thsize:4096第四个拱门:巨大尺寸:4096当前最高目录文件:direxp-tam:29053字节。最高树文件:arch-dir1.txt tam:4096字节。
以th为前缀的字符串显示在另一个线程中处理的数据。
我使用函数readdir(主线程)和readdir_r(派生线程)来读取目录条目。
我认为这可能是问题所在,但后来在所有线程下编译了调用readdir_r的程序,错误的结果仍然存在。
真的我不明白为什么文件大小返回错误(4096是我文件系统中默认的集群大小。那么为什么文件被处理为目录呢?
你能帮我一把吗?感谢
主要功能代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <pthread.h>
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<thargs*>(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;
}
我建议您检查正在进行的stat()调用的返回值。
在工作线程中,您正在打印thentry.d_name
,这看起来不错,但是,如果没有与工作目录相关的路径信息,我相信对stat(thentry.d_name,&thstat);
的调用将失败。
我不建议创建单独的线程来扫描每个目录。这个程序是I/O绑定的,所以使用多个线程不会运行得更快。如果有什么不同的话,它会运行得更慢,因为几个线程同时从不同的地方读取,迫使磁盘四处寻找。
您最好使用单个线程,对目录树进行简单的深度优先或广度优先遍历。
相关文章:
- 读取文件的最后一行并输入到链接列表时出错
- C++-试图将函数指针推回到另一个CPP文件中的矢量时出错
- .h 和.cpp文件分离时出错,但仅使用 .h 文件时没有错误.我做错了什么?
- 在 C/C++ 中打开驻留在 "/sys/" 下的文件时出错
- 在头文件中定义变量不会出错
- 如何在多写入器情况下对文件支持的共享内存中的大页面出错
- JNI,使用两个 .so 文件时出错,其中一个文件需要另一个文件
- 生成文件中隐式规则中的 -c 标志出错
- 编译时出错 - 链接.cpp和头文件
- 从人员矢量插入和读取文件时出错
- LNK2019 在文件中调用静态成员的方法时出错.cpp
- ./main:加载共享库时出错:libopencv_highgui.so.4.0:无法打开共享对象文件:没有这样的文件或
- 猫鼬 - 包含标准C++库文件时出错
- 在f2c.h文件中定义min()max()宏时出错
- ASIOSDK;从hostsample.cpp生成mex文件时出错
- 使用emscripten将c++文件转换为wasm时出错
- 编译后可执行文件出错
- 头文件C++出错
- ftell 非常大的文件出错
- 从磁盘读取映像文件出错