【问题标题】:C++ standard I/O and signalsC++ 标准 I/O 和信号
【发布时间】:2019-06-11 05:31:35
【问题描述】:

如果我调用像 read() 这样不属于 C++ 标准库的 POSIX 函数,我必须担心它会被信号中断并处理 EINTR 返回值。如果我基于this documentation 调用像fread() 这样的C++ 标准库函数,则没有提到EINTR,所以标准库似乎对用户隐藏了这一点。我的理解是否正确,这是否适用于所有 C++ 标准库函数?

更新:那么从回复中仍然不清楚的是,不能编写在每个平台上都能正常运行的标准 C++ 的结论是什么?我看到人们提到不属于标准的 POSIX 行为,所以这很令人困惑。

【问题讨论】:

标签: c++ posix


【解决方案1】:

如果我调用像 read() 这样不属于 C++ 标准库的 POSIX 函数,我必须担心它会被信号中断并处理 EINTR 返回值。

这对您的代码来说应该不是问题,因为:

  1. read 可能会失败,因此无论如何都必须处理返回值和 errno
  2. read 可以进行部分读取,因此在阻塞模式下,您必须在循环中调用 readerrno == EINTR 只是在阻塞和非阻塞模式下重试调用的另一个条件。

【讨论】:

  • 是的,我问的是使用 C++ 标准库函数以及在这种情况下需要什么。
【解决方案2】:

POSIX covers fread 也是如此,这很好,因为 C 和 C++ 标准很少提及支持 POSIX 以外的信号。它部分在fgetc 页面上说fread 可能会提前返回(可能返回0),设置ferror,并将errno 设置为EINTR。当然,如果信号导致read 短路,C 库无法检测到它,它只会再次调用read,因此您不能依赖及时响应信号。写作也是类似的。

C++标准库中很少有其他操作可以产生EINTR;不幸的是,POSIX 并未涵盖 C++,因此对于诸如 sleep_for 之类的不在 C 语言中的内容没有确定的答案。

【讨论】:

  • 标准在哪里记录?如果我查看我链接到的文档,它在哪里说 EINTR 是可能的?换句话说,您建议的平台/实现依赖于标准代码还是需要标准代码?
  • @MikeSweeney:它在fgetc 页面上,fread 推迟到该页面以防错误。 POSIX C 实现需要此行为(因此适用于基于它们构建的 C++ 实现),而不是其他 C(ir C++)系统。
【解决方案3】:

fread() 最初是 C 标准库 libc 的一部分,在 <stdio.h> 中定义。 C++ 标准库通过 C 库包装器 <cstdio> 提供相同的 fread()

read() 没有这样的包装器(可能是因为它会与istream 的版本冲突),但您仍然可以使用 C 库调用它。 read() 来自 POSIX 特定的 extension <unistd.h> 是正确的,它不是标准库的一部分,但它已经被广泛实施,并且经常与 libc 一起分发。

read() 将在失败时设置errno 也是正确的,其中一个错误可能是EINTR。另一方面,当fread() 失败时,no way 会找出发生了什么错误,所以从技术上讲,在这种情况下,EINTR 事件对用户隐藏也是正确的。实际上,fread() 如何处理任何特定于平台的细节取决于实现。但说这种模式适用于“所有 C++ 标准库函数”有点牵强 - 你真的必须逐个检查。

如果您想编写在每个平台上运行的“正常运行”的代码,请不要使用 POSIX 扩展。坚持fread() 和朋友,并接受这样一个事实,即跨平台的泛化意味着您可能无法获得平台特定的详细信息,例如错误号。由于可能的错误是特定于平台的,因此没有通用的方法可以知道您是否应该重试。

有关read()fread() 之间差异的更多详细信息是here

【讨论】:

  • 我特别说过read() 不是“C++ 标准库”的一部分,据我所知fread() 保证可以通过<cstdio> 获得每个C++ 标准。我的问题是关于在调用fread() 时是否需要担心可能会因为 EINTR 而重试。我查看了 fread 的 libc 实现,它在 EINTR 的情况下重试,这与这里的一些答案相矛盾。
  • 啊,是的,你做到了。抱歉,我陷入了一个编辑周期。删除了不正确的断言。希望它仍然能回答您的问题 - fread() 不保证任何事情,包括 EINTR 是否存在。
猜你喜欢
  • 2012-01-20
  • 2016-02-20
  • 2015-05-24
  • 1970-01-01
  • 1970-01-01
  • 2017-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多