sprintf线程安全吗?

sprintf线程安全吗?

 //Global log buffer char logBuffer[20]; logStatus (char * status, int length) { snprintf(logBuffer, 19, status); printf ("%s\n", logBuffer); } 

这个函数的线程安全性完全取决于snprintf / sprintf的线程安全性。

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

Solutions Collecting From Web of "sprintf线程安全吗?"

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

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

你的代码有几个问题。

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

然后,Linux遵守POSIX标准,这要求标准IO功能是线程安全的。

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

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

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

应用程序应确保由多个控制线程(线程或进程)对任何内存位置的访问受到限制,使得在另一个控制线程可能正在修改它时,没有任何控制线程可以读取或修改内存位置。 这种访问是使用同步线程执行的函数来限制的,并且也相对于其他线程同步内存。 [后面是提供同步的功能列表]

所以,POSIX说你的程序需要确保多线程不会同时修改logBuffer (或者在一个线程中修改logBuffer ,而在另一个线程中读取)。 如果你不坚持这一点,那么没有承诺会发生最糟糕的是logBuffer数据是乱码。 根本没有什么承诺会有什么结果。 我不知道Linux是否可以记录一个更具体的行为,但我怀疑它确实。

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

不对。

不正确,至少在POSIX功能的情况下。

所有的标准vararg函数都不是安全的 – 这包括所有的printf()族(1),也包括所有其他的variadic函数(2)

  1. 例如, sprintf()是:“MT安全区域设置| AS-不安全堆栈| AC-不安全内存” – 意思是说,如果语言环境是异步设置的,或者使用异步取消线程,则可能会失败。 换句话说,在MT环境中使用这些功能时必须特别注意。

  2. va_arg不是mt-safe:| MT-Safe种族:ap | AS-Safe | AC-Unsafe腐败| – 什么意思,需要互锁。

此外,应该明显的是,即使是完全安全的函数也可以以不安全的方式使用 – 例如,如果两个或多个线程正在操作相同的数据/内存区域,会发生什么情况。

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

“你有没有提到他们不是线程安全的引用?当我谷歌,似乎他们是”

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

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

  2. 线程可以使用相同的malloc()舞台,也就是说,如果其中一个线程会失败(即会损坏malloc舞台),那么所有连续调用malloc()都会导致严重错误 – 当然取决于系统配置 – 但这也意味着,没有人应该认为格式错误的内存分配是安全的。

由于所有的系统都提供了使用不同的本地设置的选项,很显然,这是异步的。 更改为“区域设置”设置可能会导致错误…

问候。