将参数传递给 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
的线程,这些线程将全部存储他们的文件名在同一个地方。
对于一个作业,我应该使用 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
的线程,这些线程将全部存储他们的文件名在同一个地方。