0

Edit: my question is different from the suggested question becaude I cannot poll 100's of future.get() and wait to execute the remaining program in main() thread. I am hoping the threads to return the value when the thread is done executing and then the calling function should run.

As per this question

in C++ future waits for the results and halts the next line of code

I am having the following code where I am creating about 100 async threads and then retrieving the return variable;

void BEVTest::runTests()
{   
    CameraToBEV cbevObj(RoiBbox, OutputDim, InputDim);
    // for multithreading
    std::vector<std::future<cv::Mat>> processingThread;
    std::vector<cv::Mat> opMatArr;
    
        for (int i = 0; i < jsonObjects.size(); i++) {
                processingThread.emplace_back(std::async(std::launch::async, &CameraToBEV::process,&cbevObj, std::ref(jsonObjects[i]), RoiBbox, OutputDim, InputDim));
        }
        for (auto& future : processingThread) {
            opMatArr.emplace_back(future.get());
        }
}

I am getting a run time exception of "read access violation" at the line opMatArr.emplace_back(future.get());

when I checked the processingThread variable, it shows all the future values as pending. So, if the above quote from the question is correct, shouldn't my code wait till it gets all the future values? Else otherwise this answer provides the following solution to wait till you get the future value from future.get()

auto f = std::async(std::launch::async, my_func)
    .then([] (auto fut) {
        auto result = fut.get();
        /* Do stuff when result is ready. */
    });

But this won't be possible for me because then I will have to poll all 100 future.get() and it will have an overhead which will defeat the purpose of creating threads.

I have two questions; 1> Why am I getting a run time exception? 2> How do I wait till all 100's of future.get() return value?

EDIT: I am providing my process function.

cv::Mat CameraToBEV::process(json& jsonObject, std::vector<Point2f> roibbox, Point2f opDim, Point2f ipDim)
{   // Parameters
    img_width = imgWidth = opDim.x;
    img_height = imgHeight = opDim.y;
    for (int i=0; i<roibbox.size(); i++)
    {
        roiPoints[i] = roibbox[i];
    }

    // From Centroids class
    jsonObj = jsonObject; 
    initializeCentroidMatrix();
    getBBoxes();
    transformCoordinates();

    // From Plotter class
    cv::Mat resultImg = plotLocation(finalCentroids,violationArr, ipDim, opDim);
    return resultImg;
}
The White Cloud
  • 189
  • 1
  • 11
  • 4
    There's nothing wrong with your code from what I can see. You are probably running into UB, caused by `&CameraToBEV::process`, but would need to see [mcve]. – super Jan 22 '21 at 14:18
  • @idmean yes I went through the answers, but I cannot poll 100's of future.get() and wait to execute the remaining program in main() thread. I am hoping the threads to return the value when the thread is done executing. – The White Cloud Jan 22 '21 at 14:21
  • Are you sure `jsonObjects` (or, at least, the various items within it) remains valid for the duration of the async tasks? – G.M. Jan 22 '21 at 14:35
  • @G.M. yes the process gets the reference of jsonObjects and it passes it to another local variable. So as far as i can understand it remains valid. – The White Cloud Jan 22 '21 at 14:48
  • How thread safe is `CameraToBEV::process`? – molbdnilo Jan 22 '21 at 14:48
  • @G.M. I edited to provide my process function. – The White Cloud Jan 22 '21 at 14:49
  • 1
    So not thread safe at all, then. – molbdnilo Jan 22 '21 at 14:50
  • @molbdnilo I dont know how to decide that, I have edited the the question to provide the process function – The White Cloud Jan 22 '21 at 14:50
  • 2
    You have one instance of `CameraToBEV`, and your threads read and write its member variables without a care in the world. – molbdnilo Jan 22 '21 at 14:52
  • 2
    @TheWhiteCloud If you read and write to the same data in multiple threads you need some kind of synchronization to avoid race conditions. If it's possible that each thread has it's own instance of a `CameraToBEV` (and it's not very expensive to create) that's probably a good option. – super Jan 22 '21 at 14:56
  • What is your compiler version? There were a few move-related bugs in `std::future` early on. To verify, try `processingThread.reserve(jsonObjects.size())` before starting the loop. – rustyx Jan 22 '21 at 16:28

0 Answers0