1

I've just started learning multi threaded programming and I'm trying to change a variable declared in the main function. My main function looks like this:

#include <iostream>
#include <thread>

void foo(int &args)
{
    for (int i = 0; i < 10; i++)
    {
        args = rand() % 100;
    }
}

int main()
{
    int args;
    std::thread worker(foo, args);
    for (int i = 0; i < 10; i++)
    {
        std::cout << args << std::endl;
    }
    worker.join();
}

So what I want the main function to do is to take in args as a reference and change the value which sits on that memory address. Thread however doesn't like this idea. The actual message i receive from running this small piece of code is:

/usr/bin/../lib64/gcc/x86_64-pc-linux-gnu/10.2.0/../../../../include/c++/10.2.0/thread:135:2: error: static_assert failed due to requirement '__is_invocable<void (*)(int &), int>::value' "std::thread arguments must be invocable after conversion to rvalues"
        static_assert( __is_invocable<typename decay<_Callable>::type,
        ^              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
multThread.cpp:15:17: note: in instantiation of function template specialization 'std::thread::thread<void (&)(int &), int &, void>' requested here
    std::thread worker(foo, args);

Plus even more but I find it redundant to completely fill this post with error messages. I'm not really sure what causes this issue, is it thread which only takes in rvalues or what? Thank you in advance for the help.

Dingus
  • 65
  • 1
  • 5
  • Because you pass the argument by reference, simulations reads and writes can occur. That's undefined behavior. Int is not thread safe. You should use an atomic or mutex – JHBonarius Dec 18 '20 at 13:42

2 Answers2

4

To pass a reference parameter to std::thread, you need to convert it to a reference_wrapper at the call site, like so:

std::thread worker(foo, std::ref(args));

This is because std::thread copies its arguments, and references cannot be copied.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
2

You most sent parameter inside of a std::reference_wrapper using std::ref:

int args;
std::thread worker(foo, std::ref(args));
Ghasem Ramezani
  • 2,683
  • 1
  • 13
  • 32