我有一个C库,我正在交叉编译以在Android和iOS应用程序中使用。
它利用了memcpy()
和mktime()
,所以我想知道这些函数在多线程环境中使用时是否隐式线程安全。
使用现代 Xcode 编译的 iOS 应用程序以及使用现代 Android NDK 编译的 Android 库使用基于 LLVM 的 clang 编译器。
我已经审查了以下问题,但无法找到明确的答案:
- MEMCPY过程安全吗?
- C 标准库线程中的函数安全吗?
POSIX 要求符合其标准化的所有函数都是线程安全的实现,除了相对较短的函数列表。memcpy()
和mktime()
都包含在 POSIX 中,并且都不在例外列表中,因此 POSIX 要求它们是线程安全的(但请继续阅读(。
但是,请注意,这不是使用的编译器的问题,而是支持应用程序的 C 库的问题。 我记得苹果的C库在某些方面是不合格的。 尽管如此,从线程安全的角度来看,memcpy()
和mktime()
并没有什么特别之处使它们具有固有的风险。 也就是说,没有理由期望他们访问任何共享数据,除了通过他们的参数提供给他们的任何数据。
还有摩擦。 你可以依靠memcpy()
,mktime()
不要在内部依赖静态数据,但POSIX对线程安全的要求并没有扩展到面对你通过选择参数创建的数据竞争时所记录的工作。 因此,例如,如果两个不同的线程调用memcpy()
,并且一个调用的目标区域与另一个调用的源区域或目标区域重叠,则需要线程之间的某种同步。
memcpy()
是否是线程安全的问题可能是可以讨论的。
我会说memcpy()
确实是线程安全的。它不依赖于(全局(状态,该状态可能会被正在运行的多个memcpy()
实例所破坏。然而,这并不意味着有一些魔法阻止了内存区域,内存区域同时是多个线程的复制目的地,memcpy()
被严重破坏,即复制过程作为一个整体不是原子的。您必须使用互斥体来确保原子性。
mktime()
是线程安全的,因为它不使用静态缓冲区,使用全局状态或类似状态。手册页提到了该系列中的一些函数不是线程安全的(那些函数具有相应的 *_r 函数(,但mktime()
不在其中。