1

所以假设我有以下代码,我在其中打开一个文件,逐行读取内容,然后将每一行用于其他地方的函数,然后当我完成后倒回文件。

FILE *file = Open_File();
char line[max];
while (!EndofFile()) 
{
    int length = GetLength(line);
    if (length > 0) 
    {
       DoStuffToLine(line)
    }
}
rewind(file);

我想知道是否有一种方法可以在这里使用线程来添加并发性。因为我只是在阅读文件而不是写入文件,所以我觉得我不必担心比赛条件。但是我不确定如何处理 while 循环中的代码,因为如果一个线程正在循环文件而另一个线程同时循环文件,它们是否会导致彼此跳过行,使其他错误等?解决这个问题的好方法是什么?

4

3 回答 3

2

如果您尝试这样做以提高读取性能,您可能会感到失望,因为这几乎肯定会受到磁盘 I/O 的限制。添加更多线程不会帮助操作系统和磁盘控制器更快地获取数据。

但是,如果您只是尝试并行处理数据,那就另当别论了。在这种情况下,我会将整个文件读入某个内存缓冲区,然后让您的线程并行处理它。这样,您就不必担心倒带文件指针或任何其他类似的烦人问题的线程安全性。

当然,您可能仍需要对多线程部分使用其他锁定机制,具体取决于您正在做什么,但您不必担心开始访问文件时标准库会做什么有多个线程。

于 2012-11-15T22:06:55.193 回答
1

并发增加了一些竞争条件问题:

1. EndofFile() 函数在循环开始时被求值,这个函数可能总是对两个线程返回true,然后一个线程到达文件末尾,另一个线程尝试读取文件。你永远不知道当一个线程可能正在执行时;
2、GetLength函数同样有效:当一个线程有长度信息时,长度可能会改变,因为另一个线程可能读取另一行;
3、你是按顺序读取一个文件,即使你倒带它,也可能总是出现IO指针的当前位置被其他线程改变的情况。

此外,正如 Telgin 所指出的,读取文件不是 CPU 限制的,而是 I/O 限制的,系统读取文件也是如此。您无法提高性能,因为您需要一些锁,而锁定只是为了保证线程安全引入开销。

于 2012-11-15T22:12:57.767 回答
0

我不确定这是最好的方法。但是,您可以读取该文件。然后将其存储在两个单独的对象中并读取对象而不是文件。只要确保之后进行清理。

于 2012-11-15T22:08:08.763 回答