2013-07-31 41 views
4

我正在使用Windows 7中的VS2012(64位8核)從本地硬盤讀取.csv文件。在C++中,如何使用多個線程讀取一個文件?

我正在閱讀的文件有50,000多行,每行有200多個屬性,因此讀取數據並將它們提供給相應的變量非常耗時。因此,我想知道是否可以用多線程加速它,每個線程讀取文件的一部分。

我已經google了一下,發現有人說,由於硬盤不是多線程,使用多線程來做到這一點將會實際上慢下來這是真的嗎?

如果可以讀取多個線程的文件,任何人都可以給我一個我可以學習的例子嗎?

此外,是否有可能將明確分配給CPU內核的線程或任務?

還有一個最後的問題:我用Python讀了同一個文件,並且在幾秒鐘內就完成了。 我可以知道爲什麼Python的讀取速度比C++快嗎?

+2

在C++中使用STL文件緩衝的一個簡單的示例一般地從文件中的確會慢下來發言多線程讀數。該程序可能是多線程的,但考慮磁盤控制器和讀/寫磁頭......可以構造此規則的例外情況,例如並行文件系統(您知道是否有),計算很多文件讀取塊之間的處理,以及其他一些情況。 –

+0

您可以讓一個線程讀取文件,然後將塊傳遞給多個解析器線程。理想情況下,您有一個用於保存數據的併發集合,因此工作線程可以快速有效地將解析結果插入(假設您需要將所有數據放在內存中的一個數據結構中)。 – hyde

+0

除非在讀取數據後處理數據的計算量非常大,否則使用多線程讀取文件將無濟於事。沒有看到你如何在Python和C++中實現文件讀取,很難知道爲什麼你在C++中看到更糟的性能。我猜你正在使用C++ API不正確或很差。 – Kylos

回答

2

讀取文件需要在任何語言或操作系統下創建一個系統調用,這意味着調用底層操作系統,並等待它將文件內容放入內存中(假設您通過操作系統安全檢查和所有這些)。多線程文件讀取確實會減慢你的速度,因爲你會製造更多的系統調用,使你不能執行程序並將控制權交給操作系統。

因此,最好的建議是海德的 - 如果需要的話,也許將文件解析到多個線程。如果你能夠在幾秒鐘內解析一個很大的文件,我會說它並不值得。例如,如果您正在運行圖形應用程序,那麼您肯定希望爲文件加載保留一個單獨的線程,以免凍結您的用戶界面。

在速度問題上,我猜想有兩個主要問題。首先,我懷疑python默認通過內存緩衝區讀取它的文件,這將加速執行。如果你可以緩衝你的文件讀取(這樣你可以減少系統調用),你可能會看到一些性能上的提升。另一個問題是你在Python和C++中使用哪些數據結構來加載/解析數據。在不知道代碼的情況下,我無法提出任何具體的建議,但花一點時間研究/思考適用於您的程序的不同數據結構可能會有所幫助。請記住,Python和C++的數據結構具有非常不同的性能配置文件,所以在Python中運行良好的一個可能是C++中更差的選擇。

編輯:http://www.cplusplus.com/reference/

// read a file into buffer - sgetn() example 
#include <iostream>  // std::cout, std::streambuf, std::streamsize 
#include <fstream>  // std::ifstream 

int main() { 
    char* contents; 
    std::ifstream istr ("test.txt"); 

    if (istr) { 
    std::streambuf * pbuf = istr.rdbuf(); 
    std::streamsize size = pbuf->pubseekoff(0,istr.end); 
    pbuf->pubseekoff(0,istr.beg);  // rewind 
    contents = new char [size]; 
    pbuf->sgetn (contents,size); 
    istr.close(); 
    std::cout.write (contents,size); 
    } 
    return 0; 
} 
+0

嗨,最大。非常感謝你的回答。這真的很有啓發性。你能給我一個簡單的例子,告訴我如何設置一個讀緩衝區?它是否必須降到硬件級別?非常感謝。 – ChangeMyName

+0

假設你使用的是C++ STL,你可以在這裏看看std :: filebuf的文檔:http://www.cplusplus.com/reference/fstream/filebuf/ –

+0

這種尋求和回溯的方法是正如人們抱怨的那樣,微軟的「bcp」不能用於純文件以外的任何其他功能,作爲一個附註。你可能喜歡使用'std :: vector <>'而不是普通的'char *'數組,這裏沒有什麼好的理由使用後者。 –