4 ms·
Would someone explain what the primary intent and current best-case usages of thread-local storage are? Is this more suited for certain languages than others?
by platz 6y ago
Would someone explain what the primary intent and current best-case usages of thread-local storage are?
Is this more suited for certain languages than others?
- Someone 6y agohttps://en.wikipedia.org/wiki/Thread-local_storage https://en.wikipedia.org/wiki/Thread-local_storage mentions the two most common uses: errno (historically a global variable, but on modern Unixes thread-local) and having separate threads accumulate a value, to only merge them at the end, thus decreasing contention for the merged value.
- platz 6y ago> having separate threads accumulate a value, to only merge them at the end, thus decreasing contention for the merged value. That sounds like just having scoped state in each thread that isn't global.
- saagarjha 6y agoTLS lets you name that state with the same name across threads.
- Someone 6y agoYes, but sometimes, you can’t do that. For example, programming languages with a ‘parallel for’ may use a thread pool, reusing threads between iterations, but there won’t be scope to store the state in. So, what you do in the loop: - grab thread-local variable containing local accumulator - if it doesn’t exist yet, create it and add it to the global list of all local accumulators (there’s a race here, but it will be rarely run) - do the work for the iteration - update accumulator Then, after the loop, go through the global list of accumulators and merge them.
- dblohm7 6y agoThis explanation is a bit hand-wavy, but "correct enough" for our purposes. Let us suppose that you wanted to store some per-thread data. A naive way to do that could be to have a global mapping from thread ID to a pointer to your data. To look up your data, you would obtain the id of your current thread and look it up in the map. Of course, since that map is shared across threads, you'd also need to protect it with a mutex. Operating systems themselves need to maintain per-thread data. When context-switching between threads, the OS will also switch out the current block of per-thread data. Applications can piggyback on this, so instead of needing to lock a shared map and then do a lookup to retrieve their data, it will already be available to them by virtue of the fact that it is essentially part of the current thread's context. No locking or global map lookups necessary!
- cryptonector 6y agoIt's super useful for many reasons: - to help make thread-unsafe APIs thread-safe E.g., errno, strtok(), and so on. - to store thread-private mutable globals (Thread-locals are more like thread-globals.) - to keep a reference/copy of global immutable data that might get replaced in the middle of a thread's handling of a request - to keep contextual data that you can't retrofit an API to pass explicitly (see also first item)
- spacechild1 6y agoPure Data made heavy use of thread local storage to turn the original application singleton (with lots of globals) into a threadsafe and reentrant library (libpd).
- pjc50 6y agoIIRC "jemalloc" achieves a speedup by using thread-local storage for (pointers to) bookkeeping and memory pools in preference to a heap shared between all threads - that makes it possible to do an allocation without using any synchronisation.