In an Embarcadero c++ 10.1 program, I am creating multiple instances of a thread using "new". In each instance, I need thread specific variables containing a pointer and an integer.
I tried two different declarations:
static TProgram_Control __thread * ptrPC_local;
static int __thread i_local;
and
static __declspec(thread) TProgram_Control * ptrPC_local;
static __declspec(thread) int i_local;
I tried with and without the 'static' modifier. I saw behavior from the two threads that suggested that each thread was clobbering each others value for these variables.
I added code in each thread to print out the threadID and the addresses of the two variables
PrintItem("TProg_Control_Thread(" + String(MyPCNo) + "): &ptrPC_local 0x" + IntToHex((int)&ptrPC_local,8));
PrintItem("TProg_Control_Thread(" + String(MyPCNo) + "): &i_local 0x" + IntToHex((int)&i_local,8));
PrintItem("TProg_Control_Thread(" + String(MyPCNo) + "): ThreadID " + IntToHex((int)GetCurrentThreadId(), 8));
This displays in my debug window, for thread (1) and thread (2):
TProg_Control_Thread(1): &ptrPC_local 0x00AC4788
TProg_Control_Thread(1): &i_local 0x00AC478C
TProg_Control_Thread(1): ThreadID 00001C34
TProg_Control_Thread(2): &ptrPC_local 0x00AC4788
TProg_Control_Thread(2): &i_local 0x00AC478C
TProg_Control_Thread(2): ThreadID 000014C4
Seems to show unique ThreadID but the addresses of the two variables are the same in each thread.
Do I understand the concept of thread specific variables correctly? And should I be seeing different addresses for the variables in each thread so that they don't clobber each other?
As usual, I get good advice here. Ulrich suggested that I try a minimal reproducible example. It took me awhile but I found someone who had written a Delphi test case. I rewrote it in C++ and it did exactly what I expected of thread local variables.
Here is the code (in Embarcadero C++ Console App):
So I could see that in 3 threads, each had a different address for TestVar.
I went back to my program. The structure looked exactly like the TestVar program. But, of course, it wasn't. I realized that I was setting the value in the thread variable in the constructor of the thread. In the Embarcadero C++ environment (and maybe everywhere), constructors run in the context of the calling thread. In each case, that was the main thread so my thread variable was getting set each time to main thread's address.
I moved the assignment into the Execute() function and now I correctly get different addresses for my thread variables in each thread of the program.