Hani Goc
Hani Goc

Reputation: 2441

How to launch multiple operations in a loop using multithreading c++

Introduction

I am trying to launch 4 functions in parallel: func1, func2, func3 and func4 on a 6 cores machine. Every function will iterate for 1000 times an fill vector entities. The main function is do_operations(). I have two versions of do_operations() which I posted in section source code.


Problem

By using the first version I get the following error:

std::system_error'
what():  Resource temporarily unavailable

In order to solve that problem. I added a condition in the version 2. If the number of threads is equal to 6 which is the number of the cores that I have. Then I run the threads and clear vector<thread> threads.

Am I writing the threading function correctly? what am I doing wrong.


Source code

void my_class::func1(std::vector<std::string> & entities)
{
  for(int = 0; i < 1000;i++)
  {
      mtx.lock();
      entities.push_back(to_string(i));
      mtx.unlock();
  }
}

void my_class::func2(std::vector<std::string> & entities)
{
  for(int = 0; i < 1000;i++)
  {
      mtx.lock();
      entities.push_back(to_string(i));
      mtx.unlock();
  }
}


void my_class::func3(std::vector<std::string> & entities)
{
  for(int = 0; i < 1000;i++)
  {
      mtx.lock();
      entities.push_back(to_string(i));
      mtx.unlock();
  }
}

void my_class::func4(std::vector<std::string> & entities)
{  
  for(int = 0; i < 1000;i++)
  {
      mtx.lock();
      entities.push_back(to_string(i));
      mtx.unlock();
  }
}

Version 1

void my_class::do_operations()
{
   //get number of CPUS 
   int concurentThreadsSupported = std::thread::hardware_concurrency();
   std::vector<std::thread> threads; 
   std::vector<std::string> entities;
    for(int i =0; i < 1000; i++)
    {
        threads.push_back(std::thread(&my_class::func1, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func2, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func3, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func4, this, ref(entities)));
    }
    
    for(auto &t : threads){ t.join(); }
    threads.clear();
}

Version 2

void my_class::do_operations()
{
   //get number of CPUS 
   int concurentThreadsSupported = std::thread::hardware_concurrency();
   std::vector<std::thread> threads; 
   std::vector<std::string> entities;
    for(int i =0; i < 1000; i++)
    {
        threads.push_back(std::thread(&my_class::func1, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func2, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func3, this, ref(entities)));
        threads.push_back(std::thread(&my_class::func4, this, ref(entities)));
        
          if((threads.size() == concurentThreadsSupported) || (i == 999))
          {
               for(auto &t : threads){ t.join(); }
              threads.clear();
          }
    }
}

Upvotes: 1

Views: 80

Answers (1)

Jakub Zaverka
Jakub Zaverka

Reputation: 8874

You are launching in total 4000 threads. If every thread gets 1MB stack space, then only the threads will occupy 4000MB of address space. My assumption is that you do not have full 4GB of 32-bit address space reserved for applications (something must be left for kernel and hardware). My second assumption is that if there is not enough space to allocate a new stack, it will return the message you are seeing.

Upvotes: 2

Related Questions