如何让多个线程同时读取同一个文件?

5
什么是让多个线程同时读取文件的最佳方法?
例如,如果我告诉我的程序使用4个线程运行,并且文件长度为12个字符,则我希望每个线程同时读取3个字符。
以下是我目前的内容:
线程函数:
void *thread(void *arg) {
    // can't seem to find the right solution to make it work here...
}

主函数(thread_count是线程数,text_size是文本大小):

// Number of characters each thread should read
uint16_t thread_chars_num = (text_size / thread_count);

pthread_t threads[thread_count];
for (int i = 0; i < thread_count; i++) {
    if(i == thread_count - 1) { // last thread might have more work
        thread_chars_num += (text_size % thread_count )
    }
    if (pthread_create(&threads[i], NULL, thread, &thread_chars_num) != 0) {
        fprintf(stderr, "pthread_create failed!\n");
      return EXIT_FAILURE;
    }
}

我正在考虑给线程函数提供一个结构体,其中包含开始读取的索引和停止读取的索引,但这确实很令人困惑,我似乎找不到正确的解决方案。

2
对于一个12字节的文件,最好在单个线程上完全读取其内容,然后将文件的每个部分分配给每个线程在内存中处理。 - Sergey Kalinichenko
那只是一个例子,实际上文件可能非常非常长 @dasblinkenlight - Paul Lemarchand
1
你的想法其实是正确的(在12字节的情况下很简单,但仍然如此)。你需要传递一个函数和参数给 pthread_create。该函数(start_routine)将需要将参数(arg)转换为指向你的结构体的指针,然后执行自己的工作(查找、读取、关闭)。基本上,你可以通过该参数向线程提供上下文。 - Adam Kotwasinski
1
在可移植的C中?打开几个文件。在Linux特定的C中?使用pread - user253751
非常感谢您的评论,但我只需要一个快速的示例,以便我可以继续前进。 - Paul Lemarchand
显示剩余2条评论
1个回答

4

Assuming you have a struct like:

struct ft 
{
    char* file_name;
    int start_index;
    int end_index;
};

然后在你的线程中:

void *thread(void *arg) {
    int i;
    int c;
    struct ft* fi = (struct ft*)arg;
    FILE* file = fopen(fi->file_name);
    fseek (file , fi->start_index, SEEK_SET);
    for(i = 0; i < fi->end_index - fi->start_index; i++)
    {
        c = getc(file);
        //do something
    }
}

此外,不要忘记在主线程中执行 pthread_join,这将使其等待其他线程完成。

非常感谢您的回答!我会尝试在我的程序中实现,并在有问题时与您保持联系。 - Paul Lemarchand
我想提一下,在主线程中添加对pthread_join的引用是值得的,以等待所有工作线程完成。 - Adam Kotwasinski
不知道load_file的作用,但在生成线程之前可能需要使用rewind对文件进行重置:http://www.cplusplus.com/reference/cstdio/rewind/ - mnistic
load_file 只是 fopen 和错误检查。我尝试添加 rewind 但没有任何变化。实际上,无论我在线程函数中尝试打印什么,它都不会显示在控制台中,即使它与文件没有关联。也许我不能从线程中打印任何东西?或者是因为我返回了 NULL? - Paul Lemarchand
最后,我使用了pread来处理它,因为在同一个文件上多次使用fopen会产生一些问题。 - Paul Lemarchand
显示剩余11条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接