簡體   English   中英

C中的多線程讀取和打印非常大的文件

[英]Multithreading in C to read and print a very large file

我有一個非常大的文件要讀取並執行以下操作。

  1. 打開大文件 (>50MB) 並逐行讀取
  2. 執行一些比較操作
  3. 打印比較結果
  4. 返回

當我在單線程 C 代碼中執行上述序列時,它工作正常,現在我試圖通過創建 3 個線程(我必須使用 3 個線程來使此過程更快)來使用多線程來使其更快進行讀取和比較但我沒有這樣做,因為我認為它只是重復了一些比較。

有什么方法可以讓我使用 3 個線程讀取文件的 3 個不同部分並執行一些操作?

請注意,這個答案是一個“技巧”(或者可能是分配是一個技巧?),因為它並沒有真正使過程更快。 答案假設標准 Linux 計算機具有合理的 (4G+) 內存。

簡短回答:在任何半體面的配置中,數據將移動到操作系統緩沖區中,問題實際上是 CPU 限制,而不是 IO 限制。

長答案:

雖然 50MB 的文件對於人類來說是“大”的,但對於每台現代計算機來說都是“小”的。 實際上,數據將移動到操作系統緩沖區中,並會留在那里,除非系統需要內存來執行其他任務。

鑒於數據在 (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' 可能會更快。 但是,問題要求行處理,並且鑒於這不是現實生活中的問題,不確定是否值得付出額外的努力。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM