1

我目前正在尝试编写一个程序,通过为每个新子目录创建一个线程并使用该线程来查找子目录的大小,来查找目录树的大小以及其中所有子目录的大小。这是一个非常简单的程序,但调试起来非常困难。我有很多 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。我得到了很多统计错误,但我不知道如何修复它们。

4

1 回答 1

4

当前目录不是线程本地的;这是过程的属性。因此,如果每个线程都尝试chdir. 您要么需要根据readdir不使用的结果构造完整路径名chdir,要么使用“*at”接口(openat、、fstatat等)打开相对于目录文件描述符的文件。

于 2013-04-19T23:50:01.937 回答