微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C 是否在幕后使用互斥锁处理 STDIN?

如何解决C 是否在幕后使用互斥锁处理 STDIN?

Programming Rust,2nd Edition 书中的这句话让我有点困惑,

... Rust 标准库使用互斥锁保护 stdin。 (如果没有互斥量,两个线程同时尝试从 stdin 读取会导致未定义的行为。C 有同样的问题并以同样的方式解决它:所有 C 标准输入和输出函数都获得一个在幕后锁定。唯一的区别是在 Rust 中,锁定是 API 的一部分。)

如果 C 中的两个线程使用 stdio.h 是否有处理文件句柄争用的幕后“互斥锁”?我一直认为这是你必须在 C 中明确做的事情,而不是为你做的事情。此外,如果您编译一个单线程 C 应用程序,这些 stdio 的行为是否会神奇地改变并优化掉互斥锁?

解决方法

有互斥锁吗?

如果 C 中的两个线程使用 stdio.h 是否有任何处理文件句柄争用的幕后“互斥锁”?

C 2018 7.21 7 说:

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

单线程应用程序没有互斥锁吗?

此外,如果您编译一个单线程 C 应用程序,这些 stdio 的行为是否会神奇地改变并优化掉互斥锁?

C 标准允许 C 实现这样做,因为 5.1.2.3 6 说 C 实现只需要产生 可观察的行为,该行为是由按照标准中指定的行为的程序产生的,而不是它必须以标准中描述的方式实施程序。我不知道是否有任何 C 实现这样做。由于使用 <stdio.h> 的模块可以与创建线程然后调用前一个模块的模块分开编译,除非用户要求(可能通过命令行开关或 {{ 1}} 指令)。它必须在链接时(可能通过在标准库的单线程版本中进行链接)或运行时(可能通过在产生线程之前不使用任何锁)来完成。

,

C11(2011 年发布)之前的 ISO C 标准版本中,没有多线程执行的概念。线程仅作为平台特定的扩展被个别平台支持。因此,由各个平台决定如何支持多线程以及 C 库是否是线程安全的。

例如,Microsoft Windows 平台提供了两个版本的 C 库:它允许您链接一个线程安全的库版本,一个不是线程安全的。该库的非线程安全版本适用于单线程应用程序,具有更好的性能,因为它不需要执行任何线程同步(即没有互斥锁)。

但是,由于 C11 引入了多线程执行的概念,标准要求允许多个线程同时写入同一个流。这意味着 C 库在这方面必须是线程安全的。这需要某种形式的线程同步。互斥体通常用于此目的。

此外,如果您编译一个单线程 C 应用程序,这些 stdio 的行为是否会神奇地改变并优化掉互斥锁?

我怀疑编译器是否有可能可靠地检测应用程序是单线程还是多线程。在评论部分,建议在不使用 -lpthread 编译器选项时执行某些链接器优化。但是,这可能只会影响 POSIX Threads 而不会影响 ISO C11 threads

,

我相信这是在 POSIX 中指定的,而不是在 C 标准中指定的,但您可以在这里看到它

您可以在 2017 POSIX Standrad

中看到这一点

将标准名称(例如 getc()putc() 等)映射到“更快但不安全”而不是“较慢但安全”版本是错误的. 在任何一种情况下,您仍然希望在转换现有代码时手动检查 getc()putc() 等的所有使用。选择安全绑定作为默认值,至少会导致正确的代码并保持“函数的原子性”不变性。否则会在转换后的代码中引入无缘无故的同步错误。修改 stdio (FILE *) 结构或缓冲区的其他例程也会安全同步。

在 Debian 中详细说明

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?