is sprintf thread safe?

13,320

Solution 1

There is no problem using snprintf() in multiple threads. But here you are writing to a shared string buffer, which I assume is shared across threads.

So your use of this function would not be thread safe.

Solution 2

You have several problems with your code.

  1. Your usage of snprintf is very suspicious. Don't use it just to copy a string. Generally don't pass dynamically allocated strings with whatever content as format to any of the printf functions. They interpret the contents and if there is anything in them that resembles a %-format, you are doomed.
  2. Don't use static buffers as you do. This is certainly neither thread safe not re-entrant.
  3. Either use printf with an appropriate format directly, or replace the call by puts.

Then, Linux adheres to the POSIX standard, which requires that the standard IO functions are thread safe.

Solution 3

"There is no problem using snprintf() in multiple threads."

Not true.

Not true, at least in case of POSIX functions.

All of the standard vararg functions are not mt-safe - this includes all the printf() family (1), but also every other variadic function as well (2)

  1. sprintf() for example is: "MT-Safe locale|AS-Unsafe heap|AC-Unsafe mem" - what means, that it can fail if locale is set asynchronously or if asynchronous cancellation of threads is used. In other words, special attention must be paid when using such functions in MT environment.

  2. va_arg is not mt-safe: |MT-Safe race:ap|AS-Safe|AC-Unsafe corrupt| - what means, that inter-locking is needed.

Additionally, what should be obvious, even totally mt-safe function can be used in unsafe way - what happens for example if two or more threads are operating the same data/memory areas.

Solution 4

Your question has an incorrect premise. Even if sprintf itself can be safely called from multiple threads at the same time (as I sure hope it can), your code is not protecting your global variable. The standard library can't possibly help you there.

Solution 5

Regarding your update about not worrying if the logBuffer content get garbled:

I'm not sure why you want to avoid making your function completely thread safe by using a locally allocated buffer or some synchronization mechanism, but if you want to know what POSIX has to say about it, here you go (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11):

Applications shall ensure that access to any memory location by more than one thread of control (threads or processes) is restricted such that no thread of control can read or modify a memory location while another thread of control may be modifying it. Such access is restricted using functions that synchronize thread execution and also synchronize memory with respect to other threads. [followed by a list of functions which provide synchronization]

So, POSIX says that your program needs to make sure mutilple threads won't be modifying logBuffer concurrently (or modifying logBuffer in one thread while reading it in another). If you don't hold to that, there's no promise made that the worst that will happen is garbled data in logBuffer. There's simply no promise made at all about what the results will be. I don't know if Linux might document a more specific behavior, but I doubt it does.

Share:
13,320
Jay D
Author by

Jay D

Technologist, Philanthropist, Amateur Astronomer, Walking in the "Cloud" , Silicon Valley California. "Fear is the path to the dark side. Fear leads to anger. Anger leads to hate. Hate leads to suffering. " -Master Yoda to young Skywalker. GPG Key Fingerprint: 8FC7 1E39 5D45 FFB9 3161 79A0 FFDF 48DD FE67 F788

Updated on July 28, 2022

Comments

  • Jay D
    Jay D almost 2 years

    is sprintf thread safe ?

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

    The thread safety of this function totally depends upon the thread safety of snprintf/sprintf .

    Updates : thanks for ur answers . i dont mind, if the actual contents gts messed up. but want to confirm that the sprintf would not cause a memory corruption / buffer overflow going beyond 20 bytes in this case, when multiple threads are trying to write to logBuffer ?

  • Jay D
    Jay D over 11 years
    thanks for your answer. but the question is about the sprintf behavior under multiple threads with same buffer. and NOT about how to write a multi threaded application to use a buffer !
  • Michael Burr
    Michael Burr over 11 years
    @Jay D: So you have multiple threads reading/modifying the same buffer concurrently without synchronization - they just happen to be doing it through sprintf()/snprintf(). The behavior is undefined in POSIX; I'm not sure what else you're looking for. I don't think you'll get anyone to say that the worst you'll ever see is a garbled logBuffer, even if that's by far the most likely problem you'll ever see.
  • Mawg says reinstate Monica
    Mawg says reinstate Monica over 7 years
    Do you have a refernce which says that they are not thread safe? When I Google, it seems that they are
  • Petter Friberg
    Petter Friberg almost 7 years
    Why do you not just edit your other answer or respond to the =comment under that answer, people will not understand that you are responding to a comment on your answer this way. It seems that you are responding to the initial question, btw this is probably why your previous answer (response) to the comment was deleted.
  • John
    John almost 3 years
    @Dijkgraaf I have the same question as Mawg says reinstate Monica's.
  • John
    John almost 3 years
    @Michael Burr My program crashes now and then when using such code snippet which looks like the one in this post.
  • Dijkgraaf
    Dijkgraaf almost 3 years
    @John I think you meant to address vtomazzi, I just edited his answer and didn't post it.