8

线程sprintf安全吗?

//Global log buffer 
char logBuffer[20];

logStatus (char * status, int length)
{
  snprintf(logBuffer, 19, status);
  printf ("%s\n", logBuffer);
}

该函数的线程安全完全取决于snprintf/的线程安全sprintf

更新: 感谢您的回答。我不介意,如果实际内容 gts 搞砸了。但是想确认 sprintf 在这种情况下不会导致内存损坏/缓冲区溢出超过 20 个字节,当多个线程试图写入时logBuffer

4

7 回答 7

16

snprintf()在多线程中使用没有问题。但是在这里你正在写入一个共享的字符串缓冲区,我假设它是跨线程共享的。

所以你使用这个函数不是线程安全的。

于 2012-11-14T20:00:25.887 回答
3

您的代码有几个问题。

  1. 您的使用snprintf非常可疑。不要仅仅使用它来复制字符串。通常不要将任何内容作为格式的动态分配的字符串传递给任何printf函数。他们解释内容,如果其中有任何类似于 % 格式的内容,那么您注定要失败。
  2. 不要static像你一样使用缓冲区。这当然既不是线程安全的,也不是可重入的。
  3. 要么printf直接使用适当的格式,要么将调用替换为puts.

然后,Linux 遵循 POSIX 标准,要求标准 IO 函数是线程安全的。

于 2012-11-14T20:46:10.007 回答
3

snprintf()“在多线程中使用没有问题。”

不对。

不正确,至少在 POSIX 函数的情况下。

所有标准vararg功能都不是 mt-safe - 这包括所有printf()系列 (1),但也包括所有其他variadic功能 (2)

  1. sprintf()例如:“MT-Safe locale|AS-Unsafe heap|AC-Unsafe mem”——这意味着,如果异步设置语言环境或使用异步取消线程,它可能会失败。换句话说,在 MT 环境中使用此类功能时必须特别注意。

  2. va_arg不是 mt-safe: |MT-Safe race:ap|AS-Safe|AC-不安全损坏| - 什么意思,需要联锁。

此外,显而易见的是,即使是完全 mt-safe 功能也可以以不安全的方式使用 - 例如,如果两个或多个线程正在操作相同的数据/内存区域会发生什么。

于 2015-06-03T22:05:39.380 回答
2

你的问题有一个不正确的前提。即使sprintf可以同时从多个线程安全地调用它自己(我当然希望它可以),你的代码并没有保护你的全局变量。标准库不可能帮助你。

于 2012-11-14T20:03:19.550 回答
2

关于您不必担心logBuffer内容是否出现乱码的更新:

我不确定您为什么要通过使用本地分配的缓冲区或某些同步机制来避免使您的函数完全线程安全,但是如果您想知道 POSIX 对此有什么看法,那就去吧(http://pubs .opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11):

应用程序应确保多个控制线程(线程或进程)对任何内存位置的访问受到限制,这样任何控制线程都不能读取或修改内存位置,而另一个控制线程可能正在修改它。使用同步线程执行以及相对于其他线程同步内存的函数来限制此类访问。[后跟提供同步的功能列表]

因此,POSIX 表示您的程序需要确保多个线程不会同时修改logBuffer(或在一个线程中修改同时logBuffer在另一个线程中读取它)。如果您不坚持这一点,则无法保证将发生的最坏情况是logBuffer. 对于结果将是什么,根本没有任何承诺。我不知道 Linux 是否会记录更具体的行为,但我怀疑它确实如此。

于 2012-11-15T08:51:37.787 回答
0

它不是线程安全的,因为 sprintf 所在的缓冲区在所有线程之间共享。

于 2012-11-14T20:16:32.107 回答
0

“你有没有说它们不是线程安全的参考资料?当我谷歌时,它们似乎是”

我之前对这个问题的回答已被删除/删除(为什么?),所以我会再试一次,使用不同的方法:

  1. AC(线程的异步取消):这显然是几乎所有“显然是 MT 安全”的代码都可能失败的情况,仅仅是因为线程在随机时间点被中断,所以没有任何同步方法可以保证正常工作(即任何形式的互斥锁都不能真正保证正常工作)

  2. 线程可以使用相同的 malloc() 领域,这意味着,如果其中一个线程失败(即它会损坏 malloc 领域),那么所有对 malloc() 的连续调用将/可能导致严重错误 - 这当然取决于系统配置——但这也意味着,没有人应该假设格式错误的内存(取消)分配是安全的。

由于所有系统都提供了使用不同本地设置的选项,因此很明显,异步。更改“语言环境”设置可能会导致错误...

问候。

于 2017-07-15T22:42:11.587 回答