c++multithreadingstdasyncstd-future

How to use std future and async with threading in a for loop with a shared resource as param?


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


Solution

  • 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.