2016-12-01 85 views
6

我目前正在開發一個項目,其中有一個大型文本文件(15+ GB),我試圖在文件的每一行上運行一個函數。爲了加速這個任務,我創建了4個線程,並試圖讓他們同時讀取文件。這與我有什麼:有沒有什麼辦法從文件中自動讀取一行C++

#include <stdio.h> 
#include <string> 
#include <iostream> 
#include <stdlib.h> 
#include <thread> 
#include <fstream> 

void simpleFunction(*wordlist){ 
    string word; 
    getline(*wordlist, word); 
    cout << word << endl; 
} 
int main(){ 
    int max_concurrant_threads = 4; 
    ifstream wordlist("filename.txt"); 
    thread all_threads[max_concurrant_threads]; 

    for(int i = 0; i < max_concurrant_threads; i++){ 
     all_threads[i] = thread(simpleFunction,&wordlist); 
    } 

    for (int i = 0; i < max_concurrant_threads; ++i) { 
     all_threads[i].join(); 
    } 
    return 0; 
} 

getline函數(帶「*單詞表>>字」沿着)似乎增加了指針和2個步驟讀出的值,因爲我會定期得到:

Item1 
Item2 
Item3 
Item2 

回。

所以我想知道是否有一種方法來自動讀取文件的一行?首先將其加載到數組中不起作用,因爲文件太大,我不希望一次加載文件。

我無法找到任何關於fstream和getline的原子性的悲哀。如果有readline的原子版本,或者甚至是使用鎖來實現我想要的簡單方法,那麼我都是耳朵。

在此先感謝!

+1

是否每行都是相同的大小?如果不是,那麼沒有一些同步(例如信號量或互斥體)就無法實現。 –

+4

我無法通過一個鎖來實現這一點。即使只有'read'系統調用。然而,這不是正確的方法:你應該給你的線程一行處理;那麼你沒有共享資源。 –

+1

對同一文件的併發讀取會極大地降低操作速度的可能性很高。有一個單獨的磁盤可供讀取,並且您希望通過同步執行對不同位置的非常細微的訪問。 –

回答

4

正確的方法是鎖定文件,防止所有其他進程使用它。請參閱Wikipedia: File locking。這對你來說可能太慢了,因爲你一次只讀一行。但是,如果您在每次函數調用期間正在讀取例如1000或10000行,那麼可能是實現它的最佳方式。

如果沒有其他進程訪問該文件,並且其他線程無法訪問該文件就足夠了,則可以使用在訪問文件時鎖定的互斥鎖。

void simpleFunction(*wordlist){ 
    static std::mutex io_mutex; 
    string word; 
    { 
     std::lock_guard<std::mutex> lock(io_mutex); 
     getline(*wordlist, word); 
    } 
    cout << word << endl; 
} 

來實現你的程序可以創建一個正在讀線到內存中的所有時間一個線程,而其它線程會從被存儲它們的類申請單線條的另一種方式。你需要這樣的東西:

class FileReader { 
public: 
    // This runs in its own thread 
    void readingLoop() { 
     // read lines to storage, unless there are too many lines already 
    } 

    // This is called by other threads 
    std::string getline() { 
     std::lock_guard<std::mutex> lock(storageMutex); 
     // return line from storage, and delete it 
    } 
private: 
    std::mutex storageMutex; 
    std::deque<std::string> storage; 
}; 
+0

感謝您的幫助!我在第一個示例中使用互斥體進行了測試,因爲它更容易快速實施。它正確讀取文件,並從1核心到2核心提供了顯着的加速,但在此之後變平。我想象來自3個線程的鎖會減慢它的速度。我想第二個結果將更具可擴展性,我將在稍後的日期實施。再次感謝! – tuchfarber

相關問題