0

For example, I have:

int main() 
{
    int i = 0;
    std::thread t([&] {
        for (int c = 0; c < 100; ++c)
            ++i;
    });

    t.join();

    return 0;
}

The thread t change the variable i value. I think, that when OS changes current thread it must save an old thread stack and copy a new thread stack.

How does operation system provide a right access to the i? Does it exists any explanation, how it works on an operating system level?

Does it more productive if I will use something like:

int main() 
{
    int* i = new int;
    std::thread t([&] {
        for (int c = 0; c < 100; ++c)
            ++(*i);
    });

    t.join();

    return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
voltento
  • 833
  • 10
  • 26
  • Read about capture by reference: http://en.cppreference.com/w/cpp/language/lambda (Hint: `i` is captured by reference) – Richard Critten Jul 05 '17 at 12:10
  • 7
    You *do* know how references work? And you *do* know that threads share the memory of the process? – Some programmer dude Jul 05 '17 at 12:10
  • I suppose an OS doesn't move variable really when deploying a stack. Does it use references? Or may be, it points to a stack of current thread? – voltento Jul 05 '17 at 12:19
  • I think my problem, that I don't understand how a change of stack thread works. – voltento Jul 05 '17 at 12:21
  • @voltento _Does it use references?_ Well.. _You_, explicitly tell it to capture `i` by reference, by typing `[&]`. – Algirdas Preidžius Jul 05 '17 at 12:25
  • 3
    Both threads' stacks exist in memory (at least virtually) at the same time. The OS just sets one CPU to use one or the other. Accessing another thread's stack is then a matter of knowing the address. – Margaret Bloom Jul 05 '17 at 12:28
  • @Algirdas Preidžius Does OS copy the `i` during thread changing? – voltento Jul 05 '17 at 12:28
  • @ Margaret Bloom So, It does not exist any preferences for perfomance, locate a variable in a stack or heap? Right? – voltento Jul 05 '17 at 12:31
  • It's a bit more complex than that when it comes to performance because the stack has very fast alloc/free and it is usually hot in the cache. However, the CPU doesn't fundamentally distinguish memory access "in the stack" or "in the heap" and a thread can be scheduled in another CPU. – Margaret Bloom Jul 05 '17 at 12:35
  • @voltento _Does OS copy the `i` during thread changing?_ And now, I will default to question asked before: _do you know how references work?_ – Algirdas Preidžius Jul 05 '17 at 12:41
  • @ Algirdas Preidžius Forget about a lambda, I ask about a stack changing during a thread changing, not about a lambda capture-list. – voltento Jul 05 '17 at 12:55

1 Answers1

1

There are two separate things at play in your example code: capture of local variables to a lambda function and how threads and their stacks work.

Capture of local variables when a lambda function is created works the same way regardless of whether the lambda is in the same thread or a different thread. Basically references to the variables are passed to the lambda. See How are C++11 lambdas represented and passed? for more details.

Threads, as commented by Margaret Bloom, share the address space of a process. They gave access to read and modify the same memory (including e.g. global variables). While each thread has a different stack area allocated to it, the stacks are all in the address space of the process so all threads can access the stack area of the other threads. So if a thread has a pointer or a reference to a variable in another threads stack, it can read and modify that.

Adding these 2 things together makes your example code work.

The first version of your code is probably slightly more efficient because there is one less level of indirection.

Sami Sallinen
  • 3,203
  • 12
  • 16