Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 程序能否同时对同一个文件*调用fflush()?_C_Multithreading_File_Stdio_Fflush - Fatal编程技术网

C 程序能否同时对同一个文件*调用fflush()?

C 程序能否同时对同一个文件*调用fflush()?,c,multithreading,file,stdio,fflush,C,Multithreading,File,Stdio,Fflush,如果多个线程同时调用同一个file*变量上的fflush(),是否会发生任何不好的情况(如未定义的行为、文件损坏等) 澄清:我不是指同时编写文件。我只是指同时冲洗 线程不会同时读取或写入文件(它们只在关键部分内写入文件,一次一个线程)。它们只在关键部分之外刷新,以便更快地释放关键部分,以便让其他人完成其他工作(文件写入除外) 虽然可能会发生一个线程正在写入文件(在关键部分内),而另一个线程正在刷新文件(在关键部分外)。答案非常简单,但您可能不会这样做,因为文件只有一个“当前位置”。你是如何跟踪它

如果多个线程同时调用同一个
file*
变量上的
fflush()
,是否会发生任何不好的情况(如未定义的行为、文件损坏等)

澄清:我不是指同时编写文件。我只是指同时冲洗

线程不会同时读取或写入文件(它们只在关键部分内写入文件,一次一个线程)。它们只在关键部分之外刷新,以便更快地释放关键部分,以便让其他人完成其他工作(文件写入除外)


虽然可能会发生一个线程正在写入文件(在关键部分内),而另一个线程正在刷新文件(在关键部分外)。

答案非常简单,但您可能不会这样做,因为文件只有一个“当前位置”。你是如何跟踪它的?文件是按顺序访问还是随机访问打开的?在后一种情况下,您可以多次打开它(每个线程一次),但仍然可以设计方法来保持文件结构的一致性。

您不应该在输入流上调用
fflush()
,它调用未定义的行为,因此我假设流是以写入或更新模式打开的

如果流在更新模式下打开(
“w+”
“r+”
),则调用
fflush()
时,最后一个操作不得为读取操作。由于流在各种线程中异步使用,因此如果不进行某种形式的进程间通信和同步或锁定(如果执行任何读取),则很难确保这一点。仍然有正当理由以更新模式打开文件,但请确保在启动
fflush
线程后不进行任何读取

fflush()
不修改当前位置。它只会导致任何缓冲输出写入系统。流通常由锁保护,因此在一个线程中调用
fflush()
,不应扰乱另一个线程执行的输出,但它可能会更改系统写入的时间。如果多个线程输出相同的
文件*
,则交错发生的顺序无论如何都是不确定的。此外,如果使用
fseek()
是同一流的不同线程,则必须使用自己的锁来确保
fseek()
与以下输出之间的一致性

虽然这样做似乎还可以,但可能不建议这样做。您可以在每个线程中的写操作之后,在释放锁之前调用
fflush()

C1中的流是线程安全的2。在访问it3之前,需要函数来锁定流

fflush函数是线程安全的,可以在任何时候从任何线程调用,只要流是输出流或更新流4


1根据现行标准,即C11

2(引用自:ISO/IEC 9899:201x 7.21.3第7节)
每个流都有一个关联的锁,用于防止多个流发生数据争用 执行线程访问流,并限制流操作的交错 由多个线程执行。一次只能有一个线程持有此锁。锁坏了 可重入:单个线程可能在给定时间多次持有锁

3(引用自:ISO/IEC 9899:201x 7.21.3-8)
所有读取、写入、定位或查询流位置的函数都会锁定流 在访问它之前。当访问被取消时,它们释放与流关联的锁 完成 可重入:单个线程可能在给定时间多次持有锁

4(引用自:ISO/IEC 9899:201x 7.21.5.2 fflush功能2)
If流指向输出流或更新流,其中最近的 未输入操作,fflush函数会导致该流的任何未写入数据 发送到主机环境并写入文件;否则,该行为是错误的
未定义。

POSIX.1c要求在字符流(由指向文件类型对象的指针表示)上运行的POSIX.1和C语言函数以实现可重入性的方式实现(见ISO/IEC 9945:1-1996,§8.2)

这一要求有一个缺点;由于为了实现可重入性,必须在函数的实现中内置同步,因此它会造成严重的性能损失。POSIX.1c通过引入以下C语言标准I/O函数的高性能但不可重入(潜在不安全)版本,解决了可重入性(安全)和性能之间的这种折衷:getc()、getchar()、putc()和putchar()。不可重入的版本被命名为getc_unlocked(),以此类推,以强调它们的不安全性


但是请注意,正如其他人所指出的:许多流行的系统(包括Windows和Android)都不符合POSIX。

实际的答案似乎是流本身(意味着)线程安全,但是,如果不是这样的话,您的问题可能是另一个线程正在写入时发生的
fflush
(在临界段内)


因此,我会使用您正在编写代码的虚拟机的模型,并将
fflush()
也放在一个关键部分中。

好的,我应该将此添加到问题中:线程不会同时读取或写入文件(它们只在一个关键部分中写入文件,一次一个线程)它们只在临界区外冲出,以便更快地释放关键部分,以便让其他人做其他工作(除了文件编写)。<代码> FFLUHSUE()/Cux>不修改当前位置。然后,可以更容易地考虑不同的方式,创建另一个工作线程(没有窗口、定时器、消息队列等)。它将只执行刷新(或者也可能是写入?)