【问题标题】:Is `asprintf` thread-safe?`asprintf` 是线程安全的吗?
【发布时间】:2015-04-18 05:00:19
【问题描述】:

GNU 函数asprintf(打印到分配的字符串)线程安全吗?

(IIC,基本上,这归结为malloc 是否是线程安全的问题。)

考虑示例代码:

#define _GNU_SOURCE
#include <stdio.h>

#include "getValue.h"

char * getValue(int key) {
  char * value;
  asprintf(&value, "%d", key); // TODO: No error handling!
  // If memory allocation wasn't possible, or some other error occurs,  these  functions  will
  // return -1, and the contents of strp is undefined.
  return value;
}

在这里,我没有触及任何全局变量。如果我的getValue 在并发线程中被调用怎么办?不会有坏事发生吧?

【问题讨论】:

标签: c multithreading printf glibc asprintf


【解决方案1】:

是的,它是线程安全的,除非它读取语言环境。

asprintf

函数:int asprintf (char **ptr, const char *template, ...)
初步:| MT-安全语言环境 | AS-不安全堆 | AC-不安全的内存

关于“语言环境”exception,特别是:

使用语言环境注释的函数作为 MT 安全问题从语言环境对象读取,无需任何形式的同步。使用语言环境注释的函数与语言环境更改同时调用,其行为方式可能与其执行期间的任何活动语言环境都不对应,而是一种不可预测的混合。

这类函数被称为"conditionally" 多线程安全,因为在某些情况下它们并非如此,因此程序员需要注意这一点。

【讨论】:

  • 我刚刚查看了引用的POSIX Safety Concepts,并没有关于语言环境异常的提示。所以,为了让我能够阅读上面的“Preliminary: ...”这些行,我还需要理解“locale”、“heap”、“mem”等修饰符的含义。我在哪里可以查到这些?
  • 一些平台提供asprintf_l,它带有locale_t参数,应该是完全线程安全的。
【解决方案2】:

glibcfree software 并且可能是唯一(或最重要的)实现 asprintf 的库。

所以你可以研究(甚至contribute 来改进)它的源代码。查看其stdio-common/asprintf.clibio/vasprintf.c 源文件。

看起来确实,它以线程安全的方式调用malloc 和相关的东西。

【讨论】:

  • 是K&R函数参数样式吗?
  • 是的_IO_vasprintf
  • 2015 年在 glib ... 中使用它有什么特别的原因吗?
  • 因为没有人愿意为过渡到 C99 发送补丁。如果您关心,请填写法律文件并提出补丁。见glibc contribution checklist
猜你喜欢
  • 2021-10-12
  • 2011-10-07
  • 2012-03-02
  • 2011-10-28
  • 2023-03-14
  • 2016-08-24
  • 2011-08-16
  • 2011-09-28
  • 2010-12-14
相关资源
最近更新 更多