C fprintf命令的单行是线程安全的吗?

C fprintf命令的单行是线程安全的吗?,c,openmp,C,Openmp,我正在使用openmp,我的程序如下所示: \#pragma omp parallel for for(x = 0, y = 0, x < 5, x++, y++) function(x, y, fp); void function(int x , int y, FILE* fp); { fprintf(fp, "(%d, %d)\n", x y); } 顺序不重要,但坐标x,y应该是顺序的,即程序不应该生成类似(2,3)的东西。这种行为总是有保证的吗?我正在lin

我正在使用openmp,我的程序如下所示:

\#pragma omp parallel for

for(x = 0, y = 0, x < 5, x++, y++)

     function(x, y, fp);

void function(int x , int y, FILE* fp);
{
   fprintf(fp, "(%d, %d)\n", x y);
}

顺序不重要,但坐标x,y应该是顺序的,即程序不应该生成类似(2,3)的东西。这种行为总是有保证的吗?我正在linux上使用gcc编译器。

您的问题中有不兼容的假设。OpenMp不是C标准的一部分,因此C规范不能说明OpenMp的线程模型,也不能确保其正确功能的安全性。直到最近,C甚至没有线程模型

C11现在有自己的线程模型,在该线程模型中,操作IO流的函数是线程安全的:

每个流都有一个用于防止数据争用的关联锁 当多个执行线程访问一个流时 由多个线程执行的流操作的交错。 一次只能有一个线程持有此锁。锁是可重入的:a 单个线程可以在给定时间多次持有锁


我认为目前还没有完全实现C11的编译器,但POSIX系统上的C库通常可以满足这一特殊要求。当有这样一个符合要求的实现时,将由坐在它上面的OpenMp实现来记录它的线程模型是否与C11中的线程模型一致。

我怀疑它是否有保证,但如果您想确定,您可以直接发出
write()
系统调用,它们保证是原子的(在Posix上)。@KerrekSB,谢谢,我已经运行了这个程序多次(也增加了循环计数器),但似乎每次都能产生正确的输出。@quartz:可能是重复的,你要求的是保证,而不是经验测量。@KerrekSB:这是非常糟糕的建议。除非在非常特定的情况下,
write
不能保证一次写入是原子的,并且
write
总是可以在短时间写入后返回,在这种情况下,您必须再次调用
write
来写出剩余部分,另一个线程可以在两次
write
调用之间竞争。另一方面,对于通过相同的
文件
流进行的其他访问,stdio必须是原子的(但对于通过不同的
文件
流访问它的相同底层文件的其他用户,则不是原子的),而不仅仅是“典型的”。POSIX要求stdio
文件
s上的所有操作都与线程有关。如果要将多个单独的stdio调用分组到一个原子操作中,可以使用
flockfile
funlockfile
函数(POSIX)。@R。。当然我指的是“典型”的一个例子,即满足此要求的一系列系统。我不知道其他系统是否也有类似的功能,也不知道中世纪的POSIX实现(例如OSX)是否已经有这种功能。我记得在IRIX(据说是POSIX)上编程时,不同线程之间的角度IO有很多问题。
(0, 0)
(2, 2)
(1, 1)
(3, 3)
(4, 4)