1

由于未知原因,似乎 fopen 在关闭前被重复调用时无法打开文本文件。

我的 C 程序使用多线程,每个线程处理一种类型的输出文本文件(每种类型 11 个),每种类型都在一个单独的文件夹中。我需要维护在长时间执行期间打开的这些文件并在同一个线程中写入大量数据。

为了更好地解释它,过程如下:

1- 线程#1 启动并在一个文件夹中创建和写入 11 个文件。

2- 在不关闭以前的文件的情况下,线程#2 启动并在不同的文件夹中创建和写入另外 11 个文件。

3-与其他两个线程相同。

4-最后,当所有需要的文件都已创建并且所有线程都已完成时,除非主线程,所有文件都将关闭。

然而,令人惊讶的是,open 确实能够同时处理所有这些文件。有人对fopen的这个问题有提示吗?我不知道它是否与多线程或 fopen 可以同时处理的最大文件数有关。

我在带有 Borland 编译器的 Windows 平台上。

4

3 回答 3

1

C 运行时 (CRT) 库在 Windows XP 及更高版本中是线程安全的。此外,如果您认为 CRT 中的某些注释包含文件,则它有 20 个打开文件的限制。

因此,在您的应用程序中。单线程打开11个文件的原因是什么?通过同时编写它们,您不会获得可衡量的性能提升。事实上,您可能会使情况变得更糟,因为 C 驱动器会在尝试写入每个文件时四处移动。

取决于你的应用程序是如何设计的:打开一个文件,写入到满,关闭它,打开第二个文件,等等。

现在,将磁盘抖动的可能性乘以四,因为每个线程都在尝试对同一个 C 驱动器进行 I/O!因此,如果可能,请序列化磁盘访问。要获得真正的改进,请增加缓冲区大小。

于 2013-09-09T20:14:12.460 回答
1

问题不大可能出在fopen. fopen在下面使用open,打开文件的最大数量很可能与open.

我的猜测是您在其他地方有错误,很可能超出了数组边界。

如果您不使用任何 Windows 特定功能,则始终valgrind可以在 Linux 上使用。

如果您无法移植代码,则可以对错误进行二进制搜索。例如,将写入文件的代码注释掉一半,看看问题是否仍然存在。如果不是,则问题可能出在被注释掉的部分。如果不是,则问题出在未评论的部分。

请注意上面的“可能”一词。如果您的代码导致未定义的行为,则不能依赖该行为。即使是有缺陷的代码也可以正常运行。

于 2013-09-09T15:06:10.257 回答
1

AFAIK f 函数不是线程安全的。open 可能是 fopen 的基础,但在它下面基本上都是(最初是 Win32)函数 CreateFile、ReadFile、WriteFile 和 CloseHandle。它们是线程安全的,我建议您使用它们,而不是在 f 调用周围使用关键部分。

于 2013-09-09T15:35:08.890 回答