Reputation: 817
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
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
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