Pro_gram_mer
Pro_gram_mer

Reputation: 817

terminate called recursively c++ multithreading

I am new to threading, and I face the situation that confuses me ,I try to throw exception inside the function that I put in thread and at main() function I have a try and catch block,However I still get these error :

1. terminate called after throwing an instance of 'char const*'

2. terminate called recursively

Below is my code

mutex m;

void AccumulateRange(uint64_t &sum, uint64_t start, uint64_t end) {
    for (uint64_t i = start;i<end;++i){
        sum+=i;
        if (sum>10) 
            throw "Number Exceed";
    }
}

int main(){

    const uint64_t num_threads = 1000;
    uint64_t nums = 1000*1000*1000;
    vector<uint64_t> v(num_threads);
    vector<thread> threads;
    uint64_t steps = nums/num_threads;

    for (uint64_t i = 0;i<num_threads;++i){
        try{
            threads.push_back(thread(AccumulateRange,ref(v[i]),steps*i,(i+1)*steps));
        }
        catch (const char& exception){
            cout<<exception<<endl;
        }
    }
    for (auto &t : threads){
        if (t.joinable())
           t.join();    
    }
    uint64_t total = accumulate(begin(v),end(v),0);
    return 0;
}

Thanks in advance !

Upvotes: 2

Views: 1011

Answers (2)

pptaszni
pptaszni

Reputation: 8303

To elaborate a bit on @DeltA answer: Instead of working with std::thread and passing the exceptions with pointers, you can use std::future because it stores the thrown exceptions in its shared state:

void AccumulateRange(uint64_t& sum, uint64_t start, uint64_t end)
{
    for (uint64_t i = start; i < end; ++i)
    {
        sum += i;
        if (sum > 10)
            throw std::runtime_error("Number Exceed");
    }
}

int main()
{
    const uint64_t num_threads = 1000;
    uint64_t nums = 1000 * 1000 * 1000;
    std::vector<uint64_t> v(num_threads);
    std::vector<std::future<void>> futures;
    uint64_t steps = nums / num_threads;
    for (uint64_t i = 0; i < num_threads; ++i)
    {
        futures.push_back(std::async(std::launch::async, AccumulateRange, std::ref(v[i]), steps * i, (i + 1) * steps));
    }
    for (auto& f : futures)
    {
        try
        {
            f.get();
        }
        catch (const std::exception& e)
        {
            std::cout << e.what() << std::endl;
        }
    }
}

Upvotes: 5

DeltA
DeltA

Reputation: 584

You can't catch exceptions between threads. When an exception is thrown, the call stack gets unwound, looking for a catch. Each thread has it's own stack. An alternative could be to use some kind of global variable or queue or other mechanism to pass exceptions from the worker threads to the main thread. Check this Catching exception from worker thread in the main thread

Upvotes: 3

Related Questions