C中的多线程处理以读取和打印非常大的文件

问题描述 投票:0回答:1

我是多线程技术的新手,所以,如果这个问题看起来很愚蠢,请和我一起裸露。我有一个很大的文件要阅读,请执行以下操作。

  1. 打开大文件(> 50MB)并逐行阅读
  2. 执行一些比较动作
  3. 打印比较结果
  4. 返回

[当我在单线程C代码中执行上述序列时,它工作正常,现在我试图通过创建3个线程(我有使用3个线程来使此过程更快的任务)来使用多线程来使其更快。并进行比较,但我这样做失败,因为我发现它只是重复了一些比较。

我是否有某种方法可以使用3个线程读取文件的3个不同部分并执行某些操作?预先谢谢你。

c multithreading file-handling
1个回答
0
投票

请注意,这个答案是'trick'(或者可能是分配是一个把戏?),因为它并没有真正使过程更快。答案假定具有合理(4G +)内存的标准Linux计算机。

简短的回答:在任何半适当的配置中,数据将移入OS缓冲区,而问题实际上是CPU约束的,而不是IO约束的。

长回答:

尽管50MB的文件对于人类来说是“大”,但对于每台现代计算机来说,它都是“小”。实际上,除非系统需要内存来执行其他任务,否则数据将移入OS缓冲区并保持在那里。

鉴于数据位于(OS)内存中,问题(不是初始调用)不是IO绑定的,而是CPU的绑定。对于此3线程MT程序将发挥作用。问题成为如何将工作分散到3个文件中。理想情况下,这3个线程会将文件划分为3个(几乎)相等的块,每个块均由自身处理。

解决方案是伪代码,实际代码将不得不处理分割成块的行,错误检查等。

FILE *data_fp ;
static int block_size ;

main() {
   data_fp = fopen(...) ;
   int filesize = ftell(fp) ;
   block_size = filesize/6 ;

   for (int i=0 ; i<N_THREADS ; i++ ) {
       start_offset = filefize*((float i)/N_THREADS) ;
       pthread_create(search_start, ... , &start_offset) ;
   }
}

search_start(void *arg) {

   // Extract the offset to start
   long start_offset = * (long *) arg ;
   // Create separate FILE*, with separate position, buffers, etc.
   FILE *local_fp = fdopen(fileno(data_fp), "r") ;

   // Position at the thread specific offset
   fseek(local_fp, start_offset, SEEK_SET) ;

   char buff[256] ;  // max line size
   // Loop until EOF, some exit condition, or block_size characters processed
   for (long p = 0 ; p < block_size && fgets(buff, sizeof(buff), local_fp) ; p += strlen(buff)) {
       // Compare, check, whatever is needed
       ...
       if (need_to_stop) break ;
   } ;
   fclose(local_fp) ;

}

使用'mmap'可能使其更快。但是,问题要求进行行处理,并且鉴于这不是实际问题,因此不确定是否值得付出额外的努力。

© www.soinside.com 2019 - 2024. All rights reserved.