리눅스의 폴더에서 에 대한 스레드를 사용하여 모든 파일과 디렉토리를 읽으려고합니다. 현재 디렉토리와 현재 디렉토리 트리에서 가장 높은 파일 크기 인 &을 얻습니다.스레드 응용 프로그램에서 파일 크기 읽기 오류 (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 <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;
}