2

我正在尝试用 c 编写一个程序,该程序使用线程打印出当前工作目录的内容。当前打印了正确数量的文件,但是,有些文件会重复多次。每次我运行它时,哪些文件重复以及多少次似乎是随机的。我尝试在我认为是关键部分的地方使用互斥锁,但没有成功。

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

struct arg_struct
{
    struct dirent *current;
    struct stat buf;
};


void * mybackup (void *arguments)
{
    pthread_mutex_lock( &mutex );
    struct arg_struct *args = arguments;
    printf( "[THREAD %u] ", (unsigned int)pthread_self());
    printf( "%s ", args->current->d_name );
    printf( "(%lld bytes)\n", (long long) args->buf.st_size );
    total_bytes += args->buf.st_size;
    pthread_mutex_unlock( &mutex );
    return NULL;
}

int main (int argc, char **argv)
{
    if (argc == 1) //For part 1, when no cmd line argument is given
    {
        int children = 0;
        int thread, i;
        pthread_t tid[100];
        char * current_path = ".";
        DIR * dir = opendir((char*)current_path); //Opens the current directory
        if (dir == NULL)  //Detects failure to open directory
        {
            perror("opendir() Failed");
            return EXIT_FAILURE;
        }

        struct dirent *current;
        int rc = 0;


        while ((current = readdir(dir)) != NULL)
        {
            struct stat buf;
            char new[10000]; //Used to create the complete path name

            //Next few lines create the complete path name required for Stat()
            strcpy(new, current_path);
            strcat(new, "/");
            strcat(new, (char*)current->d_name);
            rc = stat(new, &buf);
            //rc = stat(current -> d_name, &buf);
            if (rc < 0) //Detects stat() failure
            {
                perror("stat() Failed");
                return 1;
            }
            else
            {
                if (S_ISREG(buf.st_mode)) //If directory entry is a regular file
                {
                    struct arg_struct args;
                    args.current = current;
                    args.buf = buf;
                    thread = pthread_create(&tid[children], NULL, mybackup, (void *)&args);
                    if ( thread != 0 )
                    {
                        perror( "MAIN: Could not create child thread" );
                    }
                    children++;
                }
            }
        }

        for (i = 0; i < children; i++)
        {
            pthread_join(tid[i], NULL);
        }
        printf("Total bytes: %lld\n", total_bytes);
    }

    return 0;
}
4

1 回答 1

5
{
  struct arg_struct args;
  ...
  thread = pthread_create(&tid[children], NULL, mybackup, (void *)&args);

这不可能。您传递给线程函数的(基于堆栈的)对象很可能在创建的线程有机会对其进行任何操作之前被覆盖。

您将需要malloc该结构(并处理freeing),或使用足够大的此类结构的数组(在堆栈或静态上),以便您可以为每个线程分配一个。

实际上,仅分配该结构是不够的,您不能将其dirent* current作为指针传递 - 您需要将所需的数据从它复制到您的每个线程结构中,或者可能readdir_r改用(仔细阅读手册页中的示例)。

于 2012-11-10T18:44:23.727 回答