【问题标题】:Does fwrite call any lock internally?fwrite 会在内部调用任何锁吗?
【发布时间】:2010-09-10 13:52:22
【问题描述】:

在 solaris 中,当我将 dbx 附加到正在运行的堆栈之一时,我发现对 fwrite 的调用导致 __lll_lock_wait()?

在什么情况下会发生这种情况? fwrite 是否在内部尝试获取锁?

【问题讨论】:

    标签: c file io fwrite


    【解决方案1】:

    我查看的标准(C99 和 POSIX)并没有说明关于 fwrite 的锁定或解锁 IO。

    在我的 linux 系统上,man 页面中的锁定不是很准确:

       For non-locking counterparts, see unlocked_stdio(3).
    

    实际上,有一个fwrite_unlocked 函数。 POSIX 中的标准解锁函数只有getc_unlocked()getchar_unlocked()putc_unlocked()putchar_unlocked()

    我的解释是,可能 man(3) 集中的所有缓冲 IO 都已锁定,并且您只有很少的标准化接口来执行解锁 IO。

    这些东西在线程之间锁定确实是一件好事,否则当多个线程写入 stderr 时,您可能会得到完全混乱的输出,例如

    【讨论】:

    • 这不是一件好事,因为锁定的粒度只有字节级别。也就是说,如果您同时将两个线程中的字符串或二进制块数据写入同一个文件,则可能会出现随机交错。在实践中,大多数实现都会将锁包裹在整个更大的操作中,但它们不是必需的,并且正确的代码不能依赖于它们这样做。所以锁定几乎是无用的。如果多个线程同时使用同一个文件,它可以防止内存损坏,但这样做已经是一个错误了。
    • @R.我对原则的意思是好的,那就是完全有锁定。我仍然记得在 IRIX(它不是真正的 POSIX 兼容)上,并行线程将所有内容完全交错在一个公共输出流上。但你是对的,这样做的方式可能会受到批评。
    • POSIX 在flockfile 参考页面中相当准确地描述了锁定。除了 _unlocked 之外的所有 stdio 函数必须在内部执行 flockfile/funlockfile 等效函数。
    • @jilles:好的,谢谢。很遗憾他们没有在fwrite 页面上交叉引用这个。同样在stdio.h 的页面上,我现在看到所有这些都是 POSIX 中的可选功能。
    • @Matt:我的意思是一样的FILE *。请参阅 POSIX 第 2.5 节标准 I/O 流:“所有输入的发生就像是通过连续调用 fgetc() 读取字节;所有输出都像通过连续调用 fputc() 写入字节一样发生。”这很清楚地表明,就规范而言,锁定是按字节进行的,对于交错输出没有安全性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-15
    • 2020-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多