【问题标题】:Are functions in the C standard library thread safe?C 标准库中的函数是线程安全的吗?
【发布时间】:2013-11-27 06:43:23
【问题描述】:

我在哪里可以获得明确的答案,我的memcpy(使用 Ubuntu 附带的 eglibc 实现)是否是线程安全的? - 老实说,我真的没有在文档中找到明确的“是”或“否”。

顺便说一句,对于“线程安全”,我的意思是只要可以安全地同时复制日期字节,就可以安全地同时使用memcpy。至少如果将只读数据复制到不重叠的区域,这应该是可能的。

理想情况下,我希望在 ARM 编译器文档中看到类似于 this 页面底部的列表。

【问题讨论】:

  • 我相信任何类型的memcpy() 都是线程安全的,因为我无法想象除了自动/堆栈变量之外还需要使用任何东西。
  • @trojanfoe 两个线程复制到单个堆缓冲区怎么样?单个字节可能来自一个副本或另一个,但整个副本可能会导致交错。对我来说,这闻起来像是一种竞争条件。
  • @Adam 是的,这肯定会导致问题,但不在memcpy() 是否是线程安全的范围内。调用者需要了解这样做的后果并提供对缓冲区的必要独占访问。
  • @trojanfoe - ....什么?你做过很多(任何)多线程应用程序吗?

标签: c multithreading thread-safety glibc


【解决方案1】:

这取决于功能,以及你如何使用它。

memcpy 为例,它通常是线程安全的,如果您将源和目标都私有的数据复制到单个线程。如果您写入可由另一个线程读取/写入的数据,则它不再是线程安全的,您必须保护访问。

【讨论】:

  • 你是对的,我正在寻找关于如何使用哪个函数是线程安全的文档。 - 我知道 什么 memcpy 做了并且从这个角度来看它应该是线程安全的,但我不知道它是如何它。而其他功能则更为复杂。如果一个函数的规范似乎允许线程安全的实现,它仍然完全取决于实际的代码。 - 我可以轻松编写一个运行良好但不是线程安全的memcpy
  • @temple 在调用之间不保存任何状态的函数是线程安全的。为什么会例如memcpy 在通话之间保存任何状态?根本没有理由。随机数生成,某些字符串函数,是的,它们需要在调用之间保存状态,这就是为什么你有两个可重入的这些函数的变体(名称后附有_r)。
  • 好吧,我仍然不寻找合理性,而是寻找规范或文档。
【解决方案2】:

您可以在此处找到该列表,位于章节 2.9.1 Thread-Safety : http://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_01

也就是说,这是一个 posix 要求线程安全的函数列表。所有其他函数都必须是线程安全的。 Posix 包括标准 C 库和典型的“unix”接口。 (完整列表在这里,http://pubs.opengroup.org/onlinepubs/9699919799/functions/contents.html

memcpy() 由 posix 指定,但不是 2.9.1 中列表的一部分,因此可以认为是线程安全的。

Linux 上的各种环境至少尝试尽其所能实现 posix - linux/glibc 上的函数可能是线程安全的,即使 posix 不需要它是 - 尽管这很少被记录。对于 posix 所涵盖的其他功能/库,您将得到他们的作者所记录的内容......

据我所知,posix 将thread safety 等同于重入,并保证没有内部数据竞争。但是,您应对可能的外部数据竞争负责 - 例如保护自己不被调用,例如memcpy() 具有可能同时更新的内存。

【讨论】:

【解决方案3】:

如果 glibc 函数不是线程安全的,那么手册页会这样说,并且(很可能)还会记录一个线程安全的变体。

例如,请参阅man strtok

概要 #包括

   char *strtok(char *str, const char *delim);

   char *strtok_r(char *str, const char *delim, char **saveptr);

_r(表示“可重入”)是线程安全的变体。

不幸的是,手册页没有说明函数线程安全的习惯,而只是在出现问题时才提及线程安全。

和所有函数一样,如果你给它一个指向共享资源的指针,那么它就会变成线程不安全的。由您来处理锁定。

【讨论】:

  • _r 函数是 GNU 特定的,因此不可移植 :sadface: (如果这对你很重要的话)
猜你喜欢
  • 1970-01-01
  • 2020-09-23
  • 2013-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-12
  • 2010-12-01
  • 2023-03-30
相关资源
最近更新 更多