Hello Doug!
On Thursday, June 11, 2015 at 12:33:23 PM UTC-4, Doug Mika wrote:
> Could someone quickly confirm, in the program below, we need to join() the threads because, amongst other things, the functions running inside the threads store data in a variable that is itself inside the main() thread, correct?
I wouldn't phrase it quite the way you do.
As you probably know, thread::join() causes the
calling thread (in your case the "main" thread)
to pause its execution until the thread you're
joining has completed -- that is, until the thread
function of the thread with which you're joining has
exited.
In your specific example there are three reasons
you want thread::join (or some other synchronization
mechanism):
1) You don't want to access res1 and res2 until t1
and t2 are done doing there stuff. So you wait for
t1 and t2 to finish (i.e., join them).
2) res1 and res2 are variables local to the function
"main" (on the stack). You don't want them to go out
of scope -- i.e., you don't want main to exit -- until
t1 and t2 are done. Otherwise t1 and t2 would be
accessing and modifying stack space that might be being
used for some other purpose.
3) t1 and t2 are *also* stack variables local to main.
You *really* don't want them to go out of scope until
t1 and t2 (more precisely, the execution of t1's and
t2's thread functions) are done.
Now reasons 2 and 3 are kind of hidden by the fact that
when main completes (and its local variables go out of
scope) your program exits, so you might not see any
corruption that has occurred (but you might).
Also, I wouldn't say that res1, for example, is "a
variable that is itself inside the main() thread."
res1 and res2 are variables that are in the address
space of your program (your multi-threaded process).
(They happen to be on the stack, but that is part
of your process's address space.) As such they are
available to all threads in your process. (There is
such a thing as "thread-local storage," but you're
not using it.)
It is true that res1 and res2 are variables local to
the function "main," but (in c++) there is no notion
(not counting thread-local storage) of specific variables
belonging to specific threads. "main" is a special
function, but, in general, any given function can be
called by many different threads.
It's not exactly wrong to say that the variable res1
is "inside the main() thread," but it's an odd way of
putting, and is more likely to be confusing than
helpful.
By the way (following up on an earlier post of yours)
what compiler / version and command line did you end
up using for exploring std::thread?
Happy Multi-Threaded Hacking!
K. Frank
> void f(const vector<double>& v, double* res);//take input from v; place //result in *res
> class F {
> public:
> F(const vector<double>& vv, double* p) :v{vv}, res{p} { }
> void operator()(); // place result in *res
> private:
> const vector<double>& v; //source of input
> double* res; //target for output
> };
>
> int main() {
> vector<double> some_vec;
> vector<double> vec2;
> // ...
> double res1;
> double res2;
> thread t1 {f,some_vec,&res1}; //f(some_vec,&res1) executes in a separate //thread
> thread t2 {F{vec2,&res2}}; // F{vec2,&res2}() executes in a separate //thread
> t1.join();
> t2.join();
> cout << res1 << ' ' << res2 << '\n';
> }
P.S. I haven't tested it or looked at it that closely, but
this code of yours looks correct to me.