我正在尝试在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;
}
答案 0 :(得分:5)
{
struct arg_struct args;
...
thread = pthread_create(&tid[children], NULL, mybackup, (void *)&args);
这不可能是正确的。您传递给线程函数的(基于堆栈的)对象很可能在创建的线程有机会对其执行任何操作之前被覆盖。
您需要malloc
该结构(并处理free
ing),或者使用足够大的结构数组(在堆栈或静态上),以便您可以分配一个你的每个主题。
实际上,仅仅分配该结构是不够的,您不能将dirent* current
作为指针传递 - 您需要将所需的数据从它复制到每个线程的结构,或者可能使用{{ 1}}(仔细阅读手册页中的示例)。