2

I got stuck with an implementation problem in my threading practice project. I know what I want to achieve but I dont know how. I am new in the topic of std::future and std::async so I am not even sure if the implementation is even possible in the way I imagined.

I have a NuclearPP class which has this function(It should be staright forwad).

    const error_codes::PPErrorCode& NuclearPowerPlant::Operation(const float& power_required, float& 
    power_generated)
    {
        error_codes::PPErrorCode power_plant_error_code = error_codes::success;

        float energy_required_per_core = power_required / (float)operating_generators_; 

        for (const auto& core_it : reactor_cores_)
        {
            //Threaded call of each core's GenerateEnergy(energy_required_per_core, power_generated)
        }

        //Error handling per core with param power_plant_error_code

        return power_plant_error_code;
    }

I also have a NPPCore class with a function which generates the energy:

 const error_codes::NPPCoreErrorCode& GenerateEnergy(const float& energy_required_per_core, float& 
 produced_energy)
 {
     //Compliacted stuff which adds the generated energy to the shared resource "produced_energy" received as a param
 }

My question is: How can I start a thread for every core_it->GenerateEnergy(energy_required_per_core, power_generated).

Thank you very much in forward. If you need any more information feel free to ask.

Br, Steve

Seraph
  • 43
  • 4

1 Answers1

1

First - define what information each thread shall provide.

In this case - it is probably something like this:

struct Result
{
     error_codes::NPPCoreErrorCode error;
     float produced_energy;
};

So your future type is std::future<Result>.

Then start your work in many threads:

std::vector<std::future<Result>> results;
for (const auto& core_it : reactor_cores_)
{
    auto action = [&]{
        Result res; 
        res.error = core_it.GenerateEnergy(energy_required_per_core, res.power_generated);
        return res;
    };
    // start thread
    results.emplace_back(std::async(std::launch::async, action));
}

Then wait for each thread to finish:

  for (auto& f : results) f.wait();

Then, I guess, you want to sum up:


 for (auto& f : results) {
    Result res = f.get();
    if (res.error == error_codes::success)
       power_generated += res.power_generated;
    else {
       power_plant_error_code = res.error;
       // depending on your error strategy, you might break here
       break;
   }
}


Read more here.

PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • Worked like a charm. I also planned to use a struct but I dropped the idea cause I wanted to solve the shared resource management in the threads. But it turned out it is much much more simpler this way and probably more efficient then managing the resource locks and stuff. Thank you. :) – Seraph Jan 14 '21 at 09:21