Search code examples
c++multithreadingthread-local-storage

Converting single-threaded legacy code with global variables to multithreaded code using thread-local storage


I have a code-base of legacy C/C++ code, which contains lots of functions that access global static variables, and are therefore not thread-safe. I'm looking for advice on how to convert this code to make it thread safe. It occurs to me that one way to do it would be to convert the static variables into thread-local variables, or otherwise store them in thread-local storage. This has the advantage that I don't have to rewrite a lot of code that uses the functions to pass extra context to them, just the thread-unsafe functions themselves. But in researching this, I haven't found a lot of advice on whether this is a good or bad idea. Some specific concerns I have are

  • will the accessing of TLS-based data be significantly slower?
  • am I just continuing to fall into the trap of using global variables, since "global variables are bad", or does TLS counteract the global-variables-are-bad argument?

Any other thoughts would be appreciated too.


Solution

  • The problem with using TLS is that you force thread affinity onto your clients, and they have to be aware of this and write their code to handle it accordingly. So if they have a worker thread that does the heavy lifting then they will have to marshal ALL calls to your library onto that worker thread, even for simple getters and setters. Or if some other component calls into their component on a thread pool thread (for instance) then they will have to marshal that call onto their worker thread. It's not the worst thing in the world, but it can be very inconvenient. I definitely prefer the handle/context pattern (I maintain a library that uses TLS and it has been a chore at times dealing with thread affinity).