multithreadinggccforkthread-local-storage

gcc __thread local variables post fork() in a multi-threaded program


I'm using a 'regular C' program on X86 RHEL 8 and gcc 8.5. (Although I'll probably move on to RHEL 9).

If I have a multi-threaded program using some '__thread' global variables, and a thread from that program forks(), what happens to the copies of the parents allocated thread local variables in the child process?

Do the (presumably now unreachable) instances of the thread local variable that were created for 'the other' (non-forked) threads continue to exist in the child? Or are they de-allocated (in the child process) as if those threads had ended?

I think things like memory that had been malloc()ed from other threads would persist in the child, but I wasn't sure about global TLS variables.

I'm guessing that a 'copy' of the thread local storage for the thread that did the fork() ends up being used by the child process thread.

My concern is if these 'other' instances of TLS variables from the other parent threads end up in the child process, then would subsequent forks() keep accumulating additional 'unused' TLS data (or not).

In my case, I can't end the other threads before the fork() happens.


Solution

  • Thread-local storage is just memory, no different from thread-specific stack memory. As such, it will be mapped to the new process's address space. However, since there is only one thread in the new process, this memory cannot be easily accessed.

    This should not be a concern since the memory is not copied, just mapped as copy-on-write. Nothing writes to that memory, so it's just another unused set of pages.

    What should be a concern is all the locked mutexes that will exist in the child process, without threads to unlock them. But this is described many times elsewhere.