我正在做我的作业,我要完成的是计算给定目录的目录和文件,但是我找到的每个目录都应该计入我的进程的另一个线程,这是我到目前为止:
void *dirCounter(void *param){
queue<pthread_t> queue;
dir_ptr dir = (dir_ptr)param;
dir->countDir = 0;
DIR* dirName = dir->name;
struct dirent *curr;
off_t dsp;
dsp= telldir(dirName);
while(dsp!= -1){
curr = readdir(dirName);
if(curr == NULL){
break;
}
if(!strcmp(curr->d_name,".")|!strcmp(curr->d_name,"..")) { //To avoid counting . and ..
dsp = telldir(dirName); //Actual position asociated to the stream
continue; //Executes the beginning of the while
}
if(curr->d_type == DT_DIR){
dir->countDir++; //counts directories in the first level
//For each directory found, create another thread and add it to the queue:
pthread_attr_t attr1;
pthread_t tid1;
pthread_attr_init(&attr1);
dir_ptr par1 = (dir_ptr)malloc(sizeof(directorio));
par1->name = opendir(curr->d_name);
par1->countDir = par1->countFile = 0;
pthread_create(&tid1,&attr1, dirCounter, par1);
//queue.push(tid1);
}
if(curr->d_type == DT_REG){
dir->countFile++; //Counts files
}
dsp = telldir(dirName);
}
//pthread_join(tid1, NULL);
//while(!queue.empty()){
//pthread_join(queue.front(), NULL);
// queue.pop();
//}
printf("Dirs: %d Files: %d\n", dir->countDir, dir->countFile);
pthread_exit(NULL);
}
到目前为止,如果对连接进行评论,代码会对“第一级”的当前文件和目录进行计数,然后它只会给出一个分段错误,如果该行被取消注释,它只会给出一个输出行然后死掉分段错误。 我的想法是每当我找到一个目录时创建一个线程,然后在最后加入所有它们,创建一个半递归例程。
修改:
char str[256];
strcpy(str, "./");
strcat(str, curr->d_name);
//strcat(str, "\"");
puts(str);
par1->name = opendir(str);
par1->countDir = par1->countFile = 0;
pthread_create(&tid1,&attr1, dirCounter, par1);
queue.push(tid1);
修改后的作用: 打印所有目录,但它确实给出了分段错误,而某些线程无法完成它的任务。
答案 0 :(得分:2)
问题的直接原因是dir->name
在创建的其他线程中为NULL
,因为opendir(curr->d_name);
失败。这是因为目录curr->d_name
不是绝对路径名 - opendir()
将在当前工作目录中查找您尝试打开的目录,但该目录实际上是在您目前正在处理的目录中。
我建议不要将DIR *
值传递给线程,而是简单地传递目录的路径名,让线程自己执行opendir()
。然后它应该测试返回值,并且只有在readdir()
返回非NULL时才继续调用opendir()
。
当您找到作为目录的目录条目时,您需要通过将"/"
和curr->d_name
连接到正在处理的目录的路径名来构造路径名以传递给新线程。
请注意,您根本不需要dsp
变量和telldir()
的调用。如果您有一个有效的DIR *dir
,则只需使用以下内容循环播放:
while (curr = readdir(dir)) {
/* Do something with curr */
}
答案 1 :(得分:1)
我看到了一些错误。我不确定这是否能解释你的崩溃。
您为每个目录和相应的线程分配了“directorio”的实例。但你永远不会释放它。内存泄漏。
是否打算打印整个文件系统的目录和文件总数?或者只是每个目录的单个目录和文件计数?如果是前者,则不会将结果添加回来。我甚至建议让所有线程共享dirCount和fileCount的相同整数指针。 (并使用锁定序列化访问或只使用__sync_add_and_fetch)。您也可以使用一组全局变量作为整数目录和文件计数。
如果后一种情况(每个线程打印它自己的子文件总和),只需传递一个目录名(字符串)作为线程参数,然后让线程使用堆栈中的局部变量作为计数器。 (该线程将在传入的字符串上调用opendir。它仍然需要释放传入的已分配字符串。)
您不需要将pthread_attr_t实例传递给pthread_create。您可以将NULL作为第二个参数传递并获得相同的效果。
您没有检查pthread_create的返回值。如果失败(不太可能),则tid1可能是垃圾值。
希望这有帮助。