在c中发出多线程问题

时间:2012-11-10 18:40:29

标签: c multithreading

我正在尝试在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;
}

1 个答案:

答案 0 :(得分:5)

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

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

您需要malloc该结构(并处理free ing),或者使用足够大的结构数组(在堆栈或静态上),以便您可以分配一个你的每个主题。

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