[Interest] Heavily Commented Example: Simple Single Frontend with Two BackendsLow,

K. Frank kfrank29.c at gmail.com
Sat Oct 27 05:59:05 CEST 2012


Hi d3fault!

On Fri, Oct 26, 2012 at 8:32 PM, d3fault <d3faultdotxbe at gmail.com> wrote:
> Just about threw up when I woke up and realized what I had done (I
> dream in code). Isn't the address of a stack object, when accessed
> from another thread, not guaranteed to even be valid? Doesn't each
> context/thread have it's own stack?

I believe that stack objects can be shared among threads.  (Obviously
c++ was silent on this prior to the c++11 standard.  I don't claim to
understand the memory / threading model of c++11 in detail, but I'm
not aware that it makes any distinction between stack and heap
addresses.)  While it is true that different threads have their own
stacks, I believe that these stacks are all distinct in the process's
address space.  So, as long as a local variable on one thread's stack
remains in scope, it can be accessed by another thread, provided
that you use proper thread synchronization, of course.

So, for example, suppose one thread's run method has a local variable.
This thread spawns a second thread, and passes it the address of that
local variable.  Then the first thread waits for completion of (joins)
the second thread, so that the first thread's run method doesn't
finish until the second thread is done, and therefore the first thread's
local variable doesn't go out of scope until the second thread is
done.  I believe that the second thread can safely use and modify
the local variable (subject to proper thread synchronization).

Again, my reasoning is that each thread's stack is ordinary memory
in the process's address space.  You can pass pointers to both
heap- and stack-allocated variables to functions, and the functions
neither know nor care which they are.  (If a stack variable goes out
of scope, you'll have trouble, but if a heap variable is deleted, you'll
have essentially the same trouble.)  I believe that the exact same
reasoning applies when you pass pointers to heap and stack
variables to (a function running in) another thread.

It would seem quite problematic if things didn't work this way.  You
call a function with a pointer to some object.  Remember, the function
neither knows nor cares whether that object is on the heap or stack.
But now let's say a new version of that function wants to pass that
object off to some other thread for processing.  If the heap vs. stack
distinction mattered, it wouldn't be able to, even if the object were on
the heap, because the function has no (language-based) way to where
the object resides.

> I don't know, but it just seems
> gross. The only justification I had for allocating it on the stack was
> that it would be a stronger guarantee that when run() went out of
> scope, the object would be deleted (like a QMutexLocker).

I'm not commenting on the correctness of your specific code, but I
believe that RAII would be a fine reason to use a local (stack) variable,
even if that variable is to be used by another thread.

> ...
> So I changed it to now allocate the object on the heap instead. I am
> not even sure it should have worked to begin with. Maybe I was just
> getting lucky because I'm testing on a single core x86? No idea tbh,
> but this change eases a pain in my stomach.

Again, not commenting on your specific code, but I think in principle
that no indigestion is warranted.

This is a legitimate and interesting question.  If my presumptions are
wrong about how the new c++11 standard works in this regard, I would
hope someone chimes in to set the record straight.

> ...
> d3fault

Happy Multi-Threaded Hacking!


K. Frank



More information about the Interest mailing list