我目前正在做一个项目,我有一个大的文本文件(15+ GB),我试图在文件的每一行运行一个函数。为了加快任务沿着,我创建了4个线程,并试图让他们同时读取文件。这与我有类似:
#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()
函数(和*wordlist >> word
一起)似乎是递增指针并在2个步骤中读取值,正如我经常得到的那样:
Item1
Item2
Item3
Item2
后退
所以我想知道是否有一种方法可以原子地读取文件的一行?首先将其加载到数组中不会起作用,因为文件太大了,我不希望一次加载文件。
遗憾的是,我找不到任何关于fstream
和getline()
的原子性的东西。如果有一个readline()
的原子版本,或者甚至是一个简单的使用锁来实现我想要的东西的方法,我会洗耳恭听。
2条答案
按热度按时间brqmpdu11#
正确的方法是锁定文件,这将阻止所有其他进程使用它。参见Wikipedia: File locking。这对你来说可能太慢了,因为你一次只能读一行。但是如果你在每个函数调用期间阅读1000或10000行,这可能是实现它的最佳方法。
如果没有其他进程访问该文件,并且其他线程不访问该文件就足够了,则可以使用在访问该文件时锁定的互斥量。
实现程序的另一种方法是创建一个线程,该线程一直将行阅读到内存中,而其他线程将从存储它们的类请求单行。您需要这样的东西:
fykwrbwg2#
首先将其加载到数组中是行不通的,因为文件太大了,我不希望一次分块加载文件。
因此,使用内存Map文件。操作系统将按需将文件加载到虚拟内存中,但它对您的代码是透明的,并且比使用流i/o效率高得多,您甚至可能不需要或受益于多线程。