我目前正在尝试编写一个程序,通过为每个新子目录创建一个线程并使用该线程查找子目录的大小来查找目录树的大小以及其中所有子目录的大小。这是一个非常简单的程序,但它很难调试。我有一些问题,S_ISDIR没有按预期工作(常规文件正在传递if语句,我的程序正在尝试将dir更改为常规文件)。下面是我对该问题的代码。我想让每个父目录等待子目录完成,但不希望每个子目录等待下一个子目录。
#define NAMESIZE 256
#define NUM_THREADS 100
#define MAX_PATH_LENGTH 500
int totalSum = 0;
pthread_mutex_t sum_mutex ;
pthread_mutex_t thread_mutex ;
void *findSize(void *p)
{
int levelSum = 0, numberThreads = 0, i = 0;
DIR *dir ;
struct dirent *entry ;
struct stat entry_stat ;
char cwd[2049] ;
char threads[NUM_THREADS] ;
char paths[NUM_THREADS][MAX_PATH_LENGTH];
char *path = (char*)p ;
// change into the directory that was passed in
if(chdir (p) == -1)
{
perror("chdir");
exit(1);
}
// get current working directory
if(!getcwd (cwd, 2049))
{
perror("getcwd") ;
return;
}
// open the directory to get entries within it
dir = opendir(".") ;
if(!dir)
{
perror("Cannot read directory");
return;
}
while((entry = readdir(dir)))
{
// call stat on the current entry in the directory
if(stat (entry->d_name, &entry_stat) == -1)
{
perror("stat error");
}
// skip the . and .. directories
if(strcmp (entry->d_name, ".") == 0)
continue;
if(strcmp (entry->d_name, "..") == 0)
continue;
// check if current entry is a directory
if(S_ISDIR (entry_stat.st_mode))
{
pthread_mutex_lock(&thread_mutex) ;
strcpy(paths[numberThreads], cwd) ;
strcat(paths[numberThreads], "/") ;
strcat(paths[numberThreads], entry->d_name) ;
pthread_t temp ;
// create new thread in threads array
if (pthread_create(&temp, NULL, findSize, (void *)paths[numberThreads]))
{
fprintf("failed to create thread for directory %s\n ", paths[numberThreads]) ;
exit(1) ;
}
threads[numberThreads] = temp;
// increment the number of threads created on this level of the directory tree
numberThreads++ ;
pthread_mutex_unlock(&thread_mutex) ;
}
if(S_ISREG(entry_stat.st_mode))
{
pthread_mutex_lock(&sum_mutex) ;
int fileSize = entry_stat.st_size ;
levelSum += fileSize ;
totalSum += fileSize ;
pthread_mutex_unlock(&sum_mutex) ;
}
}
void *status ;
for(i = 0; i < numberThreads; i++)
{
pthread_join(threads[i], NULL) ;
}
}
总的来说,我只是用我的函数findSize和用户传入的路径来做pthread_create。我得到了很多的stat错误,但我无法弄清楚如何修复它们。
答案 0 :(得分:4)
当前目录不是线程本地的;这是该过程的一个属性。因此,如果每个线程都尝试chdir
,你最终会做废话。您需要根据readdir
的结果构建完整路径名,而不使用chdir
,或使用“* at”接口(openat
,fstatat
等)来构建完整路径名打开相对于目录文件描述符的文件。