0
votes

In my main function, I am trying to implement multithreading similar to below,

#include <thread>
#include <mutex>
....

int main(int argc, char *argv[])
{
    std::mutex myMutex;

    while(...) {
       //some code
       std::thread t1([=,&myArr](){
          std::lock_guard<std::mutex> lockGuard(myMutex);
          for(int i=0; i<1000; i++) {
              myArr[i] = alpha*(myArr[i] - t*myArr[i-1]) ;
          }
       });

       std::thread t2([=,&myArr](){
           std::lock_guard<std::mutex> lockGuard(myMutex);
           for(int i=1000; i<2000; i++) {
               myArr[i] = alpha*(myArr[i] - t*myArr[i-1]) ;
           }
       });
       t1.join();
       t2.join();

    }

    return 0;
}

When I run the code like this myArr array is not updated as I wanted. Because of race condition. And ´´´lock_guard´´´ should help to solve this issue from my web search. But I am a bit confused about how to add that to this piece of code. I tried directly adding like below:

{
   t1.join();
   std::lock_guard<std::mutex> lockGuard(myMutex);
}
{
   t2.join();
   std::lock_guard<std::mutex> lockGuard(myMutex);
}

But it gives error : mycode.cpp:2127: error: binding reference of type ‘std::lock_guard::mutex_type& {aka std::mutex&}’ to ‘const std::mutex’ discards qualifiers std::lock_guard lockGuard(myMutex);

Is there any intelligent way to solve this issue?

1
Error message and code you shown does not match. Please provide actual code you tried - Slava
Please create a minimal reproducible example which replicates your error, and show it to use together with the full and complete build output from that example, and add comments on the lines you get the errors. - Some programmer dude
If you are trying to add mutex lock to your lambdas, then you need to capture mutex by reference. But that will make your code convoluted single threaded. - Slava
answer and comments pretty much points out the compilation error and that even with mutex code execution is sequential however i am not sure if its intended but depending on execution of t1 and t2, values in myArr can change, because myArr[i] depends on myArr[i - 1] and t1 writes to myArr[999] while t2 reads from myArr[999]. - Gaurav Dhiman

1 Answers

2
votes

There are two issues in your code that can potentially cause a compilation error, but they can both be solved by capturing the mutex by reference. As it stands, your code is trying to capture the mutex by value since it is included under the default of =.

The first issue is that a mutex cannot be captured by value because mutexes are non-copyable. The second issue is that even if you could capture a mutex by value, the captured mutex would be const within the lambda body, which would mean that it couldn't be locked. (In fact, you cannot do anything with a const reference to std::mutex.)

Again, both of these issues can be solved by capturing by reference. (Although, the resulting code still does not make sense, as it appears to force the two threads to run serially.)