2016-12-01 49 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

相关问题