【问题标题】:Is std::ifstream thread-safe & lock-free?std::ifstream 是线程安全且无锁的吗?
【发布时间】:2010-05-02 17:34:54
【问题描述】:

我打算使用 std::ifstream 执行打开以从多个线程中读取单个文件。我关心的是 std::ifstream 是否是线程安全且无锁的?

更多细节:

  1. 我在 Ubuntu 和 Windows XP 上使用 g++ 4.4,在 Leopard 上使用 4.0。
  2. 每个线程都创建自己的 std::ifstream 实例

提前致谢!

【问题讨论】:

    标签: c++ thread-safety ifstream lock-free file-locking


    【解决方案1】:

    这是实现定义的。标准 C++ 完全没有提到线程,因此任何关于线程的假设都会固有地调用未指定或实现定义的行为。

    我们需要您使用的平台更具体,但假设 ifstream 是线程安全的或无锁的可能是不合理的。如果不出意外,实际上执行从文件读取的操作系统级别调用中可能涉及锁,在这种情况下,不可能实现真正的无锁实现。即使没有这个,从 ifstream 中读取的每次都需要检查几个格式标志,并且需要根据读取过程中发生的情况更新标志位。 (即istream::good()istream::operator bool)由于不可能以原子方式完成所有这些操作,因此对istream 的线程安全特性进行过多假设是不合理的。

    【讨论】:

    • "任何关于线程的假设都会固有地调用未定义的行为" 嗯,我认为它只是意味着未指定或定义的实现。
    • @GMan:关于 g++ 4.4 和 g++ 4.0 实现的任何想法?
    • @GMan:有什么区别?
    • @Billy“未指定”行为和“实现定义”行为意味着操作必须有一些一致的结果,尽管编译器之间的结果可能不同(在“实现定义”的情况下,编译器文件必须描述预期结果)。另一方面,“未定义的行为”意味着结果可能是不可预测的、不一致的,甚至可能是奇怪的,即使在单个编译器上或什至在程序的一次执行中也是如此。
    • @Tyler McHenry:谢谢 :) 已编辑。
    【解决方案2】:

    http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_concurrency.html

    在编写该手册页时,GCC 的标准库遵循操作系统的 C stdio 文件缓冲。他们避免将状态保持在 C FILE 结构之外,并通过它实现一定程度的安全性。

    由于 C stdio 库在最后一次 I/O 操作周围的文件中实现了单个范围的缓冲区,我看不出lock-free implementation 是如何可能的。对文件的操作必须串行处理。也许无缓冲模式会有所帮助;这比我现在想做的研究多一点。

    【讨论】:

    • 需要注意的是,在并发世界中,无锁是一个比线程安全“更强”/更严格的概念。
    • 如何验证纯粹为读取而打开的文件上没有单个全局 I/O 锁?
    • @Viet:您需要检查您的操作系统文档。感谢您解释无锁是一个特殊的术语,en.wikipedia.org/wiki/Lock-free。我认为大多数(如果不是全部)C stdlib 实现在缓冲过程中为每个文件实现一个锁。听起来您想在无缓冲、希望无锁的操作系统界面上实现自己的缓冲。
    【解决方案3】:

    所有标准库都是线程安全的,但不是“异步”安全的。因此,您可以从不同的线程调用相同的函数,但不能在相同的对象上调用。

    【讨论】:

    • Err.. 如果你不能从多个线程中读取,那是 not 线程安全的。
    • 将“线程安全”视为适用于整个库的简单布尔条件有点愚蠢。例如,如果两个线程可以同时写入同一个文件,文件库是否是线程安全的,并且该库仅保证所有写入的 bytes 都在文件中结束?毕竟,在存在缓冲的情况下,这是一个合理的结果。
    猜你喜欢
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 2010-12-10
    • 2017-12-23
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多