5

I would like to define a few variables as thread-specific using the __thread storage class. But three questions make me hesitate:

  1. Is it really standard in c99? Or more to the point, how good is the compiler support?
  2. Will the variables be initialised in every thread?
  3. Do non-multi threaded programs treat them as plain-old-globals?
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
Adrian Ratnapala
  • 5,485
  • 2
  • 29
  • 39

2 Answers2

6

To answer your specific questions:

  1. No, it is not part of C99. You will not find it mentioned anywhere in the n1256.pdf (C99+TC1/2/3) or the original C99 standard.
  2. Yes, __thread variables start out with their initialized value in every new thread.
  3. From a standpoint of program behavior, thread-local storage class variables behave pretty much the same as plain globals in non-multi-threaded programs. However, they do incur a bit more runtime cost (memory and startup time), and there can be issues with limits on the size and number of thread-local variables. All this is rather complicated and varies depending on whether your program is static- or dynamic-linked and whether the variables reside in the main program or a shared library...

Outside of implementing C/POSIX (e.g. errno, etc.), thread-local storage class is actually not very useful, in my opinion. It's pretty much a crutch for avoiding cleanly passing around the necessary state in the form of a context pointer or similar. You might think it could be useful for getting around broken interfaces like qsort that don't take a context pointer, but unfortunately there is no guarantee that qsort will call the comparison function in the same thread that called qsort. It might break the job down and run it in multiple threads. Same goes for most other interfaces where this sort of workaround would be possible.

R.. GitHub STOP HELPING ICE
  • 208,859
  • 35
  • 376
  • 711
  • 1
    Of course thread-local data is always a bit of a hack, but that doesn't mean you don't sometimes need to hack. – Adrian Ratnapala Jul 29 '11 at 10:58
  • Just want to mention gnulib here. It has a thread-local-store (tls) module, that takes care for most platforms/compilers. Consider it if you are writing (L)GPL software. I wouldn't start to write platform-independent code without it - saves your lifetime and reduces headaches. – rockdaboot Jan 13 '16 at 16:13
  • Um, gnulib does not help you write platform-independent software. It helps you write software that has hard-coded platform-dependent hacks for some *N* wacky legacy platforms, and nothing else. Most of these hacks are not thread-safe and have all sorts of problematic corner-case bugs, too. – R.. GitHub STOP HELPING ICE Jan 15 '16 at 04:57
3

You probably want to read this:

http://www.akkadia.org/drepper/tls.pdf

1) MSVC doesn't support C99. GCC does and other compilers attempt GCC compatibility.

edit A breakdown of compiler support for __thread is available here:

http://chtekk.longitekk.com/index.php?/archives/2011/02/C8.html

2) Only C++ supports an initializer and it must be constant.

3) Non-multi-threaded applications are single-threaded applications.

Steve-o
  • 12,678
  • 2
  • 41
  • 60
  • 1
    So, for (1), the answer is 'No; it is not in the C99 standard'. – Jonathan Leffler Jul 29 '11 at 06:49
  • It's listed as a storage class specifier in the C99 edits http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/C99-Thread_002dLocal-Edits.html – Steve-o Jul 29 '11 at 06:59
  • @Steve-o: That does not mean it has anything to do with C99. Rather, that document is just showing how C99 would be modified to include the `__thread` keyword. The upcoming C1x is expected to include thread-local storage class, but it's definitely not part of C99. – R.. GitHub STOP HELPING ICE Jul 29 '11 at 07:39