Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 连接线混乱_C_Pthreads - Fatal编程技术网

C 连接线混乱

C 连接线混乱,c,pthreads,C,Pthreads,我正在做我的家庭作业,我必须完成的是计算给定目录的目录和文件,但我找到的每个目录也应该与我的进程的另一个线程一起计算,这是我到目前为止所做的: 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=

我正在做我的家庭作业,我必须完成的是计算给定目录的目录和文件,但我找到的每个目录也应该与我的进程的另一个线程一起计算,这是我到目前为止所做的:

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); 
}
修改后的功能:
打印所有目录,但它确实给出了分段错误,并且一些线程没有完成它的任务。

问题的直接原因是
dir->name
在创建的其他线程中
NULL
,因为
opendir(curr->d_name)正在失败。这是因为目录
curr->d_name
不是绝对路径名-
opendir()
将在当前工作目录中查找您试图打开的目录,但该目录实际上位于您当前工作的目录中

我建议不要将
DIR*
值传递给线程,而只需传递目录的路径名,让线程自己执行
opendir()。然后它应该测试返回值,如果
opendir()
返回非空值,则只继续调用
readdir()

当您发现一个目录条目是一个目录时,您需要通过将
“/”
curr->d_name
连接到正在处理的目录的路径名上来构造一个路径名以传递给新线程

请注意,您根本不需要
dsp
变量和对
telldir()
的调用。如果您有一个有效的
DIR*DIR
,只需使用以下命令即可循环:

while (curr = readdir(dir)) {
    /* Do something with curr */
}

我看到一些虫子。我不确定这是否能解释你的车祸

您为每个目录和相应的线程分配了一个“directorio”实例。但你从来没有释放它。内存泄漏

是否要打印整个文件系统的目录和文件总数?或者只是每个目录的单个目录和文件计数?如果是前者,则不会将结果添加到备份中。我甚至建议让所有线程共享相同的dirCount和fileCount整数指针。(并使用锁序列化访问或仅使用)。您也可以只使用一组全局变量来计算整数dir和文件计数

如果是后一种情况(每个线程打印自己的子文件总和),只需传递一个目录名(字符串)作为线程参数,并让线程使用堆栈中的局部变量作为计数器。(线程将对传入的字符串调用opendir。它仍然需要释放传入的已分配字符串。)

您不需要将pthread_attr_t实例传递到pthread_create中。您可以将NULL作为第二个参数传递,并获得相同的效果

您没有检查pthread_create的返回值。如果失败(不太可能),那么tid1可能是一个垃圾值


希望这会有所帮助。

非常有用,但是我无法进行此修改,但我接受了这个想法并对代码进行了一些更改,现在在我的原始帖子中的“修改”标题下:)
while (curr = readdir(dir)) {
    /* Do something with curr */
}