programmer
programmer

Reputation: 602

Using std::thread with std::mutex

I am trying mutex lock with independent threads. The requirement is, I have many threads which will run independently and access/update a common recourse. To ensure that the recourse is updated via a single task, I used mutex. However this is not working.

I have pasted code, a representation of what I am trying to do below:

#include <iostream>
#include <map>
#include <string>
#include <chrono>
#include <thread>
#include <mutex>
#include <unistd.h>


std::mutex mt;
static int iMem = 0;
int maxITr = 1000;


void renum()
{
    // Ensure that only 1 task will update the variable
    mt.lock();
    int tmpMem = iMem;
    usleep(100); // Make the system sleep/induce delay
    iMem = tmpMem + 1;    
    mt.unlock();
    printf("iMem = %d\n", iMem);
}

int main() 
{
    for (int i = 0; i < maxITr; i++) {
        std::thread mth(renum);
        mth.detach(); // Run each task in an independent thread
    }
    return 0;
}

but this is terminating with the below error:

terminate called after throwing an instance of 'std::system_error'
  what():  Resource temporarily unavailable

I want to know if the usage of <thread>.detach() is correct above? If I use .join() it works, but I want each thread to run independently and not wait for the thread to finish. I also want to know what is the best way to achieve the above logic.

Upvotes: 2

Views: 1435

Answers (1)

John Zwinck
John Zwinck

Reputation: 249153

Try this:

int main()
{
  std::vector<std::thread> mths;
  mths.reserve(maxITr);
  for (int i = 0; i < maxITr; i++) {
    mths.emplace_back(renum);
  }
  for (auto& mth : mths) {
    mth.join();
  }
}

This way, you retain control of the threads (by not calling detach()), and you can join them all at the end, so you know they have completed their tasks.

Upvotes: 3

Related Questions