在Linux上使用printf线程安全写入stdout吗?使用低级write命令怎么样?

推荐答案

它不是由C标准指定的——这取决于您对C标准库的实现.事实上,C标准甚至没有提到线程,因为某些系统(例如嵌入式系统)没有多线程.

在GNU实现(glibc)中,stdio中处理FILE*个对象的大多数高级函数都是线程安全的.那些名字中通常没有unlocked的人(例如getc_unlocked(3)).然而,线程的安全性是在每个函数调用级别上的:例如,如果您对printf(3)进行多次调用,则这些调用中的每一个都保证以原子方式输出,但其他线程可能会在您对printf()的调用之间打印出内容.如果要确保一系列I/O调用以原子方式获得输出,可以用一对flockfile(3)/funlockfile(3)个调用来锁定FILE句柄.请注意,这些函数是可重入的,因此可以在它们之间安全地调用printf(),即使printf()本身调用flockfile(),也不会导致死锁.

低级别的I/O调用(如write(2))应该是线程安全的,但我不能write(2)%确定这一点——write()会对内核进行系统调用以执行I/O.具体发生的方式取决于您使用的内核.它可能是sysenter指令,或者旧系统上的int(中断)指令.一旦进入内核,就由内核来确保I/O是线程安全的.在我刚刚对Darwin内核版本8.11.1进行的测试中,write(2)似乎是线程安全的.

Linux相关问答推荐

Microsoft ODBC Driver 18 for Python Docker Image,ARM设备;生成错误

如何根据具体情况打印两行输出?

为什么我在退出SD-Bus容器时出现错误?

没有发现运行时依赖关系,但它在S的运行时路径中有吗?

如何在 Linux 上打印带有屏蔽值的环境名称?

如何拆分和计算 Bash 中单词的出现次数?

将 Visual Studio C++ 项目迁移到 Linux 和 CMake

如何在 DolphinDB 中递归查找目录中的所有文件?

如何使用 shell 脚本将文本文件转换为 JSON 文件

使用 bash 中的数字对 RPM 内核字符串进行版本排序返回不正确的结果

用于判断 shell 脚本是否正在运行的 Linux 命令

为什么在编译 K&R2 第 1 章中最长的行示例时出现getline 的类型冲突错误?

如何克隆 OpenLDAP 数据库

Linux 上 pid_t、uid_t、gid_t 的大小

crontab 命令单独一行

polkitd未注册身份验证代理的解释

docker compose:加载共享库时出错:libz.so.1:无法从共享对象映射段:不允许操作

ngrok 如何在防火墙后工作?

Anaconda 安装后,conda 命令失败并显示ImportError: no module named conda.cli

如何将所有文件从一个目录移动(和覆盖)到另一个目录?