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

时间:2015-03-05 01:01:08

标签: c multithreading file-io pthreads

对于赋值,我应该使用pthread创建一个名为search(即递归)的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行......我打破了这个规则,只是为了试图让它工作)。

1 个答案:

答案 0 :(得分:2)

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