开放式线程安全吗?

3

如果两个线程同时调用open()函数,这样做是否可行?如何找到答案?

假设这些调用在不同的文件上进行,并且它们的标志可以是O_RDONLY、O_WRONLY或两者都有。


1
你是在对同一个文件调用open()吗?我们需要更多信息... - Nick Bastin
它们是不同的文件,但假设它们的标志可以是O_RDONLY或O_WRONLY或两者都有。 - kaykun
4个回答

5
这取决于操作系统和C运行时库。如果符合POSIX.1-2001或POSIX.1-2008标准,则必须根据此处的要求是线程安全的: http://www.kernel.org/doc/man-pages/online/pages/man7/pthreads.7.html 正如其他人所指出的,仅因为系统调用可能是线程安全的,并不意味着您可以做任何事情并期望调用会神奇地为您解决问题。如果在没有适当同步的情况下从不同的线程写入和读取同一文件,则结果将不确定。这种上下文中的线程安全性仅意味着读取和写入将被执行。另一种思考方式是,您获得与在不同进程中进行调用相同的保证,例如open()的系统调用是“进程安全”的,否则操作系统将无用。

2

既然您注意到它们是不同的文件,那么就没有问题。

这和两个不同的进程打开两个不同的文件没有什么区别。

编辑:正如 Guy 在下面的评论中指出的那样,这并非总是如此。这取决于您正在使用的libc是否是线程安全的。现代版本针对open()调用是线程安全的。


这并不总是正确的。例如,在旧版本的Microsoft C中,运行时库不是线程安全的(不可重入)。我相信在很久以前Linux / Unix也是如此。 - Guy Sirton
虽然这是一个公正的观点,但我认为在今天你会很难找到那种行为。 - Brian Roach
同意。混乱主要集中在引入线程和多核系统方面,人们开始看到一些东西出现问题。 - Guy Sirton

1

无论它们是指向同一个文件还是不同的文件,这实际上都是一个红鲱鱼。如果你在类Unix操作系统上运行时,当open()是一个直接的系统调用时,答案绝对是肯定的。不同的线程可以同时打开文件(甚至是相同的文件),就像不同的进程一样。

如果你在一个模拟open()的用户空间系统上运行,非线程安全的可能来源是文件描述符表,该表将操作系统返回的文件句柄映射到类Unix open()调用返回的小整数文件描述符。正如另一个帖子所指出的那样,POSIX要求open()是线程安全的,并且由于open()通常实现为提供POSIX兼容性,因此它是安全的。

虽然很有可能会遇到非线程安全的open(),但这种情况只会发生在非常老旧和不稳定的C库中。特别是如果你正在使用POSIX线程。


-1

这要看情况。你是打开来读取吗?那么是安全的。如果你是打开来写入,那么你应该同步线程。


此外,sqlite3声称在多个线程上进行读取时是安全的。 - Daniel A. White

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接