【发布时间】:2017-11-26 20:13:05
【问题描述】:
我是线程新手,我相信我理解这个概念。由于锁是使用线程的必要工具,但(或至少对我而言)对如何使用感到困惑,我需要使用它们,但似乎无法正确使用它们。这里的想法是搜索目录以查找 CSV 文件。 (将在 CSV 上完成更多工作,但这与此处无关)我有一个算法可以在不使用线程的情况下搜索可以正常工作的目录。 (请记住,搜索目录是一种非常适合递归的任务,因为您需要搜索一个目录以找到另一个目录,当您找到新目录时,您要搜索该目录)因为我需要使用线程在查找新目录的每个实例上,我都设置了两次相同的算法。一旦在 main 中找到目录并调用函数(通过线程)来搜索找到的目录。同样,如果我在没有线程的情况下使用此方法,我的问题为零,但是通过线程,我发送给函数的参数将被覆盖。即使我锁定了整个功能,也会发生这种情况。显然我没有正确使用锁和线程,但是我要去哪里错了。我有测试目录来验证它是否正常工作。我在“。”中有 3 个目录。目录,然后是除此之外的子目录。它可以很好地找到前三个目录(在 main 中),然后当它将这些目录传递给线程函数时,它将搜索三个不同的时间,但通常不止一次搜索同一个目录。换句话说,路径名似乎被覆盖了。我会发布代码,这样你就可以看到我在做什么。我提前谢谢你。完整代码链接:sorter.h https://pastebin.com/0vQZbrmhsorter.c https://pastebin.com/9wd8aa74dirWorker.c https://pastebin.com/Jd4i1ecr
在 sorter.h 中
#define MAXTHREAD 255
extern pthread_mutex_t lock;
typedef
struct _dir_proc
{
char* path; //the path to the new found directory
char* colName; //related to the other work that must be done
} dir_proc;
在 sorter.c 中
#include <pthread.h>
#include <assert.h>
#include <dirent.h>
#include "sorter.h"
pthread_mutex_t lock;
int main(int argc, char* argv[])
{
int err = 0;
pthread_t threads[MAXTHREAD];
DIR *dirPointer;
char* searchedDirectory = ".";
struct dirent *directEntry;
dir_proc *dir_proc_args = malloc(sizeof(struct _dir_proc));
assert(dir_proc_args != NULL);
dir_proc_args->path = (char*) malloc(256 * (sizeof(char));
assert(dir_proc_args->path != NULL);
dir_proc_args->colName = (char*) malloc(256 * sizeof(char));
assert(dir_proc_args->colName != NULL);
pthread_mutex_init(&lock, NULL)
//dir_proc_args->colName is saved here
if(!(dirPointer = opendir(searchedDirectory)))
{
fprintf(stderr, "opening of directory has failed");
exit(1);
}
while((directEntry = readdir(dirPointer)) != NULL)
{
//do stuff here to ensure it is a directory
//ensure that the dir we are looking at is not current or parent dir
//copy path of found directory to dir_proc_args->path
err = pthread_create(&threads[count++], NULL, &CSVFinder, (void*)dir_proc_args);
if(err != 0)
printf("can't create thread);
}
int i;
for(i=0; i < count; ++i)
{
pthread_join(threads[i], NULL);
}
pthread_mutex_destroy(&lock);
}
在 CSVFinder 函数中
#include <assert.h>
#include <pthread.h>
#include "sorter.h"
#include <dirent.h>
void *CSVFinder(void *args)
{
pthread_mutex_lock(&lock); //I have locked the entire function to see I can get it to work. this makes no sense to actually do
DIR *dirPointer;
struct dirent *directEntry;
dir_proc *funcArgs = (struct _dir_proc*)args;
char path[255];
strncpy(path, funcArgs->path, sizeof(path));
if(!(dirPointer = opendir(funcArgs->path)))
{
fprintf(stderr, "opening of directory has failed");
exit(1);
}
while((directEntry = readdir(dirPointer)) != NULL)
{
if(directEntry->d_type == DT_DIR) //if we are looking at a directory
{
//make sure the dir we are looking at is not current or parent dir
snprintf(funcArgs->path, (sizeof(path) + sizeof(directEntry->d_name)), "%s/%s", path, directEntry->d_name);
//I would like to be able to do a recursive call here
//to search for more directories but one thing at a time
}
}
closedir(dirPointer);
pthread_mutex_unlock(&lock);
return(NULL);
}
我希望我没有遗漏任何相关代码。我试图将代码保持在最低限度,同时不遗漏任何必要的内容。
【问题讨论】:
-
'因为我需要在查找新目录的每个实例上使用线程' - 不,不要那样做。它不会有效,(事实上,适得其反)。使用一个线程执行 I/O 绑定目录/文件扫描,如果需要对每个文件执行 CPU 密集型任务(例如压缩),则将文件规范(在一些合适的结构中)排队,以一个线程池。
-
啊,但你没有把我带到这里。我必须这样做。我完全同意你所说的。在现实生活中我永远不会这样做,但这是任务,我必须这样做。这没有任何意义。
-
好吧,分配 'dir_proc *dir_proc_args' 并加载它就可以了..除了你只做一次然后为每个线程使用相同的 dir_proc_args 实例。这不会有好的结局。 malloc 为每个线程分配一个单独的实例,否则“您发送给函数的参数将被覆盖”。
-
count声明/初始化在哪里?您还缺少您的printfs 之一的结束"。发布您实际运行的代码是最有帮助的,如果可能,最好复制粘贴。 -
@MartinJames 这可能是问题的解决方案。我将 malloc 移动到循环内,它似乎正在工作。我将继续测试和扩展。实际上我最初是这样写的,但是代码给了我一个问题,我认为循环中的 malloc 给了我一个问题,所以我移动了它。我不能感谢你。我不得不承认我很困惑为什么这会解决问题。每次循环通过时,我都会更改结构的内容。
标签: c multithreading mutex locks