将参数传递给 pthread 会导致重复 C

Passing in arguments to pthread results in duplicates C

对于一个作业,我应该使用 pthread 创建一个称为搜索(递归)的 grep 的多线程版本,其中参数是 ./search pattern ~/dir ~/dir2 ~/dir3.. etc。作业还特别指出,我应该在最后使用 pthread_exit(NULL) 来加入所有线程,并且我应该为我打开的每个文件创建一个线程。这意味着只要找到的每一行都在单独的行上,输出就会混乱。这意味着当我传入两个具有搜索模式 Hello:

的相同文件时,输出可能看起来像这样
$ ./search Hello ~/files/file2.txt ~/files/file.txt

2 ~/files/file.txt Hello world 4
1 ~/files/file2.txt Hello there 9
^           ^            ^      ^
argument #, file found, line, line #

我已经让它在没有多线程的情况下工作,一切看起来都很正常。但是,我无法让传递给 pthread_create 的参数结构真正传递正确的东西。

我有一个名为 create_file_thread 的方法,它接收要打开的文件名及其所在参数的索引。然后我有一个名为 thread_array 的全局变量结构,如下所示:

struct thread_struct {
    char file_name[256];
    int arg_id;
};
struct thread_struct thread_array[200];

我将传递给 create_file_thread 的 file_name 和索引存储到此结构中,然后将其传递给 pthread_create,如下所示:

void create_file_thread(char *file_name, int i)
{
    pthread_t threads[NUM_THREADS]; // NUM_THREADS = 200
    strcpy(thread_array[i].file_name, file_name);
    thread_array[i].arg_id = i + 1; // offset i
    int rc;
    if((rc = pthread_create(&threads[i], NULL, grep_file, &thread_array[i])))    
        exit(-1); // error
}

为了确保,我每次调用它时都打印出 thread_array[i].file_name,它最终会给我正确的文件名。

这里是 grep_file() 的简化版本(作为测试,我只是打印出传入的文件名):

void * grep_file(void *arg)
{
    struct thread_struct *thread = arg;
    char file_name[256];
    strcpy(file_name, thread->file_name);
    int id = thread->thread_id;
    printf("File name: %s\n", file_name);
    return NULL;
}

如果我将 ~/files/file.txt 作为参数 1 传入,将 ~/files/file2.txt 作为参数 2 传入,我应该将其视为输出:

File name: ~/files/file.txt
File name: ~/files/file2.txt

然而,我最终得到的是:

File name: ~/files/file.txt
File name: ~/files/file.txt

奇怪的是,有时我会得到正确的输出,但大多数时候我会重复给出的第一个参数。因为它只创建两个线程,所以我最终得到了两次相同的输出,而不是有两个具有不同文件名的输出。如何停止将参数结构传递给 grep_file 以停止重复?

编辑:

完整代码如下:http://pastebin.com/QWSFh9Zh

作为一个警告,由于一些(愚蠢的)限制(比如函数不能超过 5 行。我打破这条规则只是为了让它工作),所以它非常混乱。

我没有发现传递单个文件的问题,但如果传递包含多个文件的目录,grep_directory() 将启动多个具有相同值 id 的线程,这些线程将全部存储他们的文件名在同一个地方。