[英]Multithreading in C to read and print a very large file
我有一個非常大的文件要讀取並執行以下操作。
當我在單線程 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.