Catching exception from worker thread in the main thread












3














I didn't find a concise answer to the following problem:I have a producer - consumer threading model where main thread is the consumer while some worker thread is the producer.The producer thread runs it's thread loop during the application execution and it is possible for it to throw exceptions occasionally.The main thread is UI thread which should pop-up exception messages including those coming from different threads. How can I catch these exceptions in the main thread?



Using boost on Windows with C++0x



WorkerThread.cpp



WorkerThread::WorkerThread(){

m_thread = boost::thread(&WorkerThread::drawThread,this);

}

void WorkerThread::drawThread()
{

while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
try{

///some work is done here...

}catch(std::exception &e){

/// some exception is thrown
/// notify main thread of the exception
}

}


}


Important to note that I have no ability to wrap WorkerThread in the main thread with try{}catch as it is created at some point and from then on runs on its own till the application termination.










share|improve this question




















  • 7




    Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
    – Jonathan Wakely
    Aug 13 '14 at 10:08










  • Thanks for the tip :)
    – Michael IV
    Aug 13 '14 at 10:46
















3














I didn't find a concise answer to the following problem:I have a producer - consumer threading model where main thread is the consumer while some worker thread is the producer.The producer thread runs it's thread loop during the application execution and it is possible for it to throw exceptions occasionally.The main thread is UI thread which should pop-up exception messages including those coming from different threads. How can I catch these exceptions in the main thread?



Using boost on Windows with C++0x



WorkerThread.cpp



WorkerThread::WorkerThread(){

m_thread = boost::thread(&WorkerThread::drawThread,this);

}

void WorkerThread::drawThread()
{

while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
try{

///some work is done here...

}catch(std::exception &e){

/// some exception is thrown
/// notify main thread of the exception
}

}


}


Important to note that I have no ability to wrap WorkerThread in the main thread with try{}catch as it is created at some point and from then on runs on its own till the application termination.










share|improve this question




















  • 7




    Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
    – Jonathan Wakely
    Aug 13 '14 at 10:08










  • Thanks for the tip :)
    – Michael IV
    Aug 13 '14 at 10:46














3












3








3


5





I didn't find a concise answer to the following problem:I have a producer - consumer threading model where main thread is the consumer while some worker thread is the producer.The producer thread runs it's thread loop during the application execution and it is possible for it to throw exceptions occasionally.The main thread is UI thread which should pop-up exception messages including those coming from different threads. How can I catch these exceptions in the main thread?



Using boost on Windows with C++0x



WorkerThread.cpp



WorkerThread::WorkerThread(){

m_thread = boost::thread(&WorkerThread::drawThread,this);

}

void WorkerThread::drawThread()
{

while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
try{

///some work is done here...

}catch(std::exception &e){

/// some exception is thrown
/// notify main thread of the exception
}

}


}


Important to note that I have no ability to wrap WorkerThread in the main thread with try{}catch as it is created at some point and from then on runs on its own till the application termination.










share|improve this question















I didn't find a concise answer to the following problem:I have a producer - consumer threading model where main thread is the consumer while some worker thread is the producer.The producer thread runs it's thread loop during the application execution and it is possible for it to throw exceptions occasionally.The main thread is UI thread which should pop-up exception messages including those coming from different threads. How can I catch these exceptions in the main thread?



Using boost on Windows with C++0x



WorkerThread.cpp



WorkerThread::WorkerThread(){

m_thread = boost::thread(&WorkerThread::drawThread,this);

}

void WorkerThread::drawThread()
{

while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
try{

///some work is done here...

}catch(std::exception &e){

/// some exception is thrown
/// notify main thread of the exception
}

}


}


Important to note that I have no ability to wrap WorkerThread in the main thread with try{}catch as it is created at some point and from then on runs on its own till the application termination.







c++ multithreading boost






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 13 '14 at 10:47

























asked Aug 13 '14 at 9:24









Michael IV

5,117862152




5,117862152








  • 7




    Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
    – Jonathan Wakely
    Aug 13 '14 at 10:08










  • Thanks for the tip :)
    – Michael IV
    Aug 13 '14 at 10:46














  • 7




    Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
    – Jonathan Wakely
    Aug 13 '14 at 10:08










  • Thanks for the tip :)
    – Michael IV
    Aug 13 '14 at 10:46








7




7




Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
– Jonathan Wakely
Aug 13 '14 at 10:08




Dear internet, you do not need to use bind with thread. Just say m_thread = boost::thread(&WorkerThread::drawThread, this);
– Jonathan Wakely
Aug 13 '14 at 10:08












Thanks for the tip :)
– Michael IV
Aug 13 '14 at 10:46




Thanks for the tip :)
– Michael IV
Aug 13 '14 at 10:46












4 Answers
4






active

oldest

votes


















10














Firstly, you do not need to use bind with thread. Doing so just adds unnecessary copying and makes the code harder to read. I wish everyone would stop doing that.



WorkerThread::WorkerThread(){

m_thread = boost::thread(&WorkerThread::drawThread, this);

}


You can store an exception in an exception_ptr and pass that to the other thread, e.g. in std::queue<std::exception_ptr>:



void WorkerThread::drawThread()
{
while(true)
{
boost::unique_lock<boost::mutex> lock(m_mutex);
try{

///some work is done here...

}catch(std::exception &e){
m_queue.push(std::current_exception());
}
}
}

std::exception_ptr WorkerThread::last_exception()
{
boost::lock_guard<boost::mutex> lock(m_mutex);
std::exception_ptr e;
if (!m_queue.empty())
{
e = m_queue.front();
m_queue.pop();
}
return e;
}


Then in the other thread rethrow it and handle it:



if (auto ep = workerThread.last_exception())
{
// do something with exception
try
{
std::rethrow_exception(ep);
}
catch (const std::exception& e)
{
std::cerr << "Error in worker thread: " << e.what() << 'n';
}
}


If you can't use std::exception_ptr Boost has its own implementation of it, but I'm not sure what the Boost equivalent of current_exception is. You might need to wrap the exception in another object so the Boost exception propagation mechanism can store it.



You might want to use a separate mutex for the exception queue from the main work loop (and move the m_mutex lock inside the try block) depending how long m_mutex is usually locked by the worker thread.





A different approach uses C++11 futures, which handle passing exceptions between threads more conveniently. You need some way for the main thread to get a future for each unit of work the worker thread runs, which can be done with std::packaged_task:



class WorkerThread
{
public:
WorkerThread(); // start m_thread, as before

template<typename F, typename... Args>
std::future<void> post(F f, Args&&... args)
{
Task task(std::bind<void>(f, std::forward<Args>(args)...));
auto fut = task.get_future();
std::lock_guard<std::mutex> lock(m_mutex);
m_tasks.push(std::move(task));
return fut;
}

private:
void drawThread();
std::mutex m_mutex;
using Task = std::packaged_task<void()>;
std::queue<Task> m_tasks;
std::thread m_thread;
};

void WorkerThread::drawThread()
{
Task task;
while(true)
{
{
std::lock_guard<std::mutex> lock(m_mutex);
task = std::move(m_tasks.front());
m_tasks.pop();
}
task(); // run the task
}
}


When the task is run any exceptions will be caught, stored in an exception_ptr and held until the result is read through the associated future.



// other thread:

auto fut = workerThread.post(&someDrawingFunc, arg1, arg2);
...
// check future for errors
try {
fut.get();
} catch (const std::exception& e) {
// handle it
}


The producer thread could store the future objects in a queue when posting work to the consumer, and some other piece of code could check each future in the queue to see if it's ready and call get() to handle any exception.






share|improve this answer



















  • 1




    +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
    – ComicSansMS
    Aug 13 '14 at 11:21










  • In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
    – ikh
    Aug 13 '14 at 11:22










  • @Jonathan Wakely Any special reason you use lock_guard in your example?
    – Michael IV
    Aug 13 '14 at 11:23










  • @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
    – Jonathan Wakely
    Aug 13 '14 at 11:23












  • @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
    – Jonathan Wakely
    Aug 13 '14 at 11:25





















4














Those answer suggest you to send exception_ptr to main thread manually. That's not bad way, but I suggest you another way: std::promise / boost::promise.



(Since I don't have boost in this computer now, so I'll go with std::promise. However, there may be no big difference with boost.)



Look the example code:



#include <iostream>
#include <exception>
#include <thread>
#include <future>
#include <chrono>

void foo()
{
throw "mission failure >o<";
}

int main()
{
std::promise<void> prm;

std::thread thrd([&prm] {
try
{
std::this_thread::sleep_for(std::chrono::seconds(5));
foo();
prm.set_value();
}
catch (...)
{
prm.set_exception(std::current_exception());
}
});

std::future<void> fu = prm.get_future();
for (int i = 0; ; i++)
{
if (fu.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
break;
std::cout << "waiting ... [" << i << "]n";
}

try
{
fu.get();
std::cout << "mission complete!n";
}
catch (const char *msg)
{
std::cerr << "exception: " << msg << "n";
}

thrd.join(); /* sorry for my compiler's absence of std::promise::set_value_at_thread_exit */
}


The benefit of this way is 1. you don't have to manage exceptions manually - std::promise and std::future will do everything and 2. you can use all feature around std::future. In this case, I'm doing other things (outputing waiting... message) while waiting the thread exit, through std::future::wait_for.






share|improve this answer



















  • 1




    The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
    – Jonathan Wakely
    Aug 13 '14 at 10:52








  • 1




    The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
    – Jonathan Wakely
    Aug 13 '14 at 10:56










  • @JonathanWakely packaged_task?? I can't understand.. could you explain more?
    – ikh
    Aug 13 '14 at 11:08










  • I added another example to my answer, using packaged_task
    – Jonathan Wakely
    Aug 13 '14 at 11:14



















1














In the worker thread, you can catch the exception, and then retrieve a std::exception_ptr using std::current_exception. You can then store this somewhere, pick it up in the main thread, and throw it with std::rethrow_exception.






share|improve this answer





















  • can you elaborate on how it is actually done?
    – Michael IV
    Aug 13 '14 at 9:28










  • What do you mean?
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:28










  • I mean that what you said I have already read in several places but none really explains how to do it.
    – Michael IV
    Aug 13 '14 at 9:29










  • What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:31






  • 1




    The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
    – Jonathan Wakely
    Aug 13 '14 at 10:05





















1














Exceptions are synchronous. Which means there is no way to pass them between threads as exceptions. You cannot tell to any old thread "stop whatever you are doing and handle this". (Well you can if you deliver a POSIX signal to it, but that's not quite a C++ exception).



You can of course always pass an object with the exception data (as opposed to the state of being in an exception-handling mode) to another thread in the same way you would pass any other data between threads. A concurrent queue will do. Then you process it in the target thread. The target thread should be actively reading data from the queue.






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25282620%2fcatching-exception-from-worker-thread-in-the-main-thread%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    4 Answers
    4






    active

    oldest

    votes








    4 Answers
    4






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    10














    Firstly, you do not need to use bind with thread. Doing so just adds unnecessary copying and makes the code harder to read. I wish everyone would stop doing that.



    WorkerThread::WorkerThread(){

    m_thread = boost::thread(&WorkerThread::drawThread, this);

    }


    You can store an exception in an exception_ptr and pass that to the other thread, e.g. in std::queue<std::exception_ptr>:



    void WorkerThread::drawThread()
    {
    while(true)
    {
    boost::unique_lock<boost::mutex> lock(m_mutex);
    try{

    ///some work is done here...

    }catch(std::exception &e){
    m_queue.push(std::current_exception());
    }
    }
    }

    std::exception_ptr WorkerThread::last_exception()
    {
    boost::lock_guard<boost::mutex> lock(m_mutex);
    std::exception_ptr e;
    if (!m_queue.empty())
    {
    e = m_queue.front();
    m_queue.pop();
    }
    return e;
    }


    Then in the other thread rethrow it and handle it:



    if (auto ep = workerThread.last_exception())
    {
    // do something with exception
    try
    {
    std::rethrow_exception(ep);
    }
    catch (const std::exception& e)
    {
    std::cerr << "Error in worker thread: " << e.what() << 'n';
    }
    }


    If you can't use std::exception_ptr Boost has its own implementation of it, but I'm not sure what the Boost equivalent of current_exception is. You might need to wrap the exception in another object so the Boost exception propagation mechanism can store it.



    You might want to use a separate mutex for the exception queue from the main work loop (and move the m_mutex lock inside the try block) depending how long m_mutex is usually locked by the worker thread.





    A different approach uses C++11 futures, which handle passing exceptions between threads more conveniently. You need some way for the main thread to get a future for each unit of work the worker thread runs, which can be done with std::packaged_task:



    class WorkerThread
    {
    public:
    WorkerThread(); // start m_thread, as before

    template<typename F, typename... Args>
    std::future<void> post(F f, Args&&... args)
    {
    Task task(std::bind<void>(f, std::forward<Args>(args)...));
    auto fut = task.get_future();
    std::lock_guard<std::mutex> lock(m_mutex);
    m_tasks.push(std::move(task));
    return fut;
    }

    private:
    void drawThread();
    std::mutex m_mutex;
    using Task = std::packaged_task<void()>;
    std::queue<Task> m_tasks;
    std::thread m_thread;
    };

    void WorkerThread::drawThread()
    {
    Task task;
    while(true)
    {
    {
    std::lock_guard<std::mutex> lock(m_mutex);
    task = std::move(m_tasks.front());
    m_tasks.pop();
    }
    task(); // run the task
    }
    }


    When the task is run any exceptions will be caught, stored in an exception_ptr and held until the result is read through the associated future.



    // other thread:

    auto fut = workerThread.post(&someDrawingFunc, arg1, arg2);
    ...
    // check future for errors
    try {
    fut.get();
    } catch (const std::exception& e) {
    // handle it
    }


    The producer thread could store the future objects in a queue when posting work to the consumer, and some other piece of code could check each future in the queue to see if it's ready and call get() to handle any exception.






    share|improve this answer



















    • 1




      +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
      – ComicSansMS
      Aug 13 '14 at 11:21










    • In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
      – ikh
      Aug 13 '14 at 11:22










    • @Jonathan Wakely Any special reason you use lock_guard in your example?
      – Michael IV
      Aug 13 '14 at 11:23










    • @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
      – Jonathan Wakely
      Aug 13 '14 at 11:23












    • @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
      – Jonathan Wakely
      Aug 13 '14 at 11:25


















    10














    Firstly, you do not need to use bind with thread. Doing so just adds unnecessary copying and makes the code harder to read. I wish everyone would stop doing that.



    WorkerThread::WorkerThread(){

    m_thread = boost::thread(&WorkerThread::drawThread, this);

    }


    You can store an exception in an exception_ptr and pass that to the other thread, e.g. in std::queue<std::exception_ptr>:



    void WorkerThread::drawThread()
    {
    while(true)
    {
    boost::unique_lock<boost::mutex> lock(m_mutex);
    try{

    ///some work is done here...

    }catch(std::exception &e){
    m_queue.push(std::current_exception());
    }
    }
    }

    std::exception_ptr WorkerThread::last_exception()
    {
    boost::lock_guard<boost::mutex> lock(m_mutex);
    std::exception_ptr e;
    if (!m_queue.empty())
    {
    e = m_queue.front();
    m_queue.pop();
    }
    return e;
    }


    Then in the other thread rethrow it and handle it:



    if (auto ep = workerThread.last_exception())
    {
    // do something with exception
    try
    {
    std::rethrow_exception(ep);
    }
    catch (const std::exception& e)
    {
    std::cerr << "Error in worker thread: " << e.what() << 'n';
    }
    }


    If you can't use std::exception_ptr Boost has its own implementation of it, but I'm not sure what the Boost equivalent of current_exception is. You might need to wrap the exception in another object so the Boost exception propagation mechanism can store it.



    You might want to use a separate mutex for the exception queue from the main work loop (and move the m_mutex lock inside the try block) depending how long m_mutex is usually locked by the worker thread.





    A different approach uses C++11 futures, which handle passing exceptions between threads more conveniently. You need some way for the main thread to get a future for each unit of work the worker thread runs, which can be done with std::packaged_task:



    class WorkerThread
    {
    public:
    WorkerThread(); // start m_thread, as before

    template<typename F, typename... Args>
    std::future<void> post(F f, Args&&... args)
    {
    Task task(std::bind<void>(f, std::forward<Args>(args)...));
    auto fut = task.get_future();
    std::lock_guard<std::mutex> lock(m_mutex);
    m_tasks.push(std::move(task));
    return fut;
    }

    private:
    void drawThread();
    std::mutex m_mutex;
    using Task = std::packaged_task<void()>;
    std::queue<Task> m_tasks;
    std::thread m_thread;
    };

    void WorkerThread::drawThread()
    {
    Task task;
    while(true)
    {
    {
    std::lock_guard<std::mutex> lock(m_mutex);
    task = std::move(m_tasks.front());
    m_tasks.pop();
    }
    task(); // run the task
    }
    }


    When the task is run any exceptions will be caught, stored in an exception_ptr and held until the result is read through the associated future.



    // other thread:

    auto fut = workerThread.post(&someDrawingFunc, arg1, arg2);
    ...
    // check future for errors
    try {
    fut.get();
    } catch (const std::exception& e) {
    // handle it
    }


    The producer thread could store the future objects in a queue when posting work to the consumer, and some other piece of code could check each future in the queue to see if it's ready and call get() to handle any exception.






    share|improve this answer



















    • 1




      +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
      – ComicSansMS
      Aug 13 '14 at 11:21










    • In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
      – ikh
      Aug 13 '14 at 11:22










    • @Jonathan Wakely Any special reason you use lock_guard in your example?
      – Michael IV
      Aug 13 '14 at 11:23










    • @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
      – Jonathan Wakely
      Aug 13 '14 at 11:23












    • @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
      – Jonathan Wakely
      Aug 13 '14 at 11:25
















    10












    10








    10






    Firstly, you do not need to use bind with thread. Doing so just adds unnecessary copying and makes the code harder to read. I wish everyone would stop doing that.



    WorkerThread::WorkerThread(){

    m_thread = boost::thread(&WorkerThread::drawThread, this);

    }


    You can store an exception in an exception_ptr and pass that to the other thread, e.g. in std::queue<std::exception_ptr>:



    void WorkerThread::drawThread()
    {
    while(true)
    {
    boost::unique_lock<boost::mutex> lock(m_mutex);
    try{

    ///some work is done here...

    }catch(std::exception &e){
    m_queue.push(std::current_exception());
    }
    }
    }

    std::exception_ptr WorkerThread::last_exception()
    {
    boost::lock_guard<boost::mutex> lock(m_mutex);
    std::exception_ptr e;
    if (!m_queue.empty())
    {
    e = m_queue.front();
    m_queue.pop();
    }
    return e;
    }


    Then in the other thread rethrow it and handle it:



    if (auto ep = workerThread.last_exception())
    {
    // do something with exception
    try
    {
    std::rethrow_exception(ep);
    }
    catch (const std::exception& e)
    {
    std::cerr << "Error in worker thread: " << e.what() << 'n';
    }
    }


    If you can't use std::exception_ptr Boost has its own implementation of it, but I'm not sure what the Boost equivalent of current_exception is. You might need to wrap the exception in another object so the Boost exception propagation mechanism can store it.



    You might want to use a separate mutex for the exception queue from the main work loop (and move the m_mutex lock inside the try block) depending how long m_mutex is usually locked by the worker thread.





    A different approach uses C++11 futures, which handle passing exceptions between threads more conveniently. You need some way for the main thread to get a future for each unit of work the worker thread runs, which can be done with std::packaged_task:



    class WorkerThread
    {
    public:
    WorkerThread(); // start m_thread, as before

    template<typename F, typename... Args>
    std::future<void> post(F f, Args&&... args)
    {
    Task task(std::bind<void>(f, std::forward<Args>(args)...));
    auto fut = task.get_future();
    std::lock_guard<std::mutex> lock(m_mutex);
    m_tasks.push(std::move(task));
    return fut;
    }

    private:
    void drawThread();
    std::mutex m_mutex;
    using Task = std::packaged_task<void()>;
    std::queue<Task> m_tasks;
    std::thread m_thread;
    };

    void WorkerThread::drawThread()
    {
    Task task;
    while(true)
    {
    {
    std::lock_guard<std::mutex> lock(m_mutex);
    task = std::move(m_tasks.front());
    m_tasks.pop();
    }
    task(); // run the task
    }
    }


    When the task is run any exceptions will be caught, stored in an exception_ptr and held until the result is read through the associated future.



    // other thread:

    auto fut = workerThread.post(&someDrawingFunc, arg1, arg2);
    ...
    // check future for errors
    try {
    fut.get();
    } catch (const std::exception& e) {
    // handle it
    }


    The producer thread could store the future objects in a queue when posting work to the consumer, and some other piece of code could check each future in the queue to see if it's ready and call get() to handle any exception.






    share|improve this answer














    Firstly, you do not need to use bind with thread. Doing so just adds unnecessary copying and makes the code harder to read. I wish everyone would stop doing that.



    WorkerThread::WorkerThread(){

    m_thread = boost::thread(&WorkerThread::drawThread, this);

    }


    You can store an exception in an exception_ptr and pass that to the other thread, e.g. in std::queue<std::exception_ptr>:



    void WorkerThread::drawThread()
    {
    while(true)
    {
    boost::unique_lock<boost::mutex> lock(m_mutex);
    try{

    ///some work is done here...

    }catch(std::exception &e){
    m_queue.push(std::current_exception());
    }
    }
    }

    std::exception_ptr WorkerThread::last_exception()
    {
    boost::lock_guard<boost::mutex> lock(m_mutex);
    std::exception_ptr e;
    if (!m_queue.empty())
    {
    e = m_queue.front();
    m_queue.pop();
    }
    return e;
    }


    Then in the other thread rethrow it and handle it:



    if (auto ep = workerThread.last_exception())
    {
    // do something with exception
    try
    {
    std::rethrow_exception(ep);
    }
    catch (const std::exception& e)
    {
    std::cerr << "Error in worker thread: " << e.what() << 'n';
    }
    }


    If you can't use std::exception_ptr Boost has its own implementation of it, but I'm not sure what the Boost equivalent of current_exception is. You might need to wrap the exception in another object so the Boost exception propagation mechanism can store it.



    You might want to use a separate mutex for the exception queue from the main work loop (and move the m_mutex lock inside the try block) depending how long m_mutex is usually locked by the worker thread.





    A different approach uses C++11 futures, which handle passing exceptions between threads more conveniently. You need some way for the main thread to get a future for each unit of work the worker thread runs, which can be done with std::packaged_task:



    class WorkerThread
    {
    public:
    WorkerThread(); // start m_thread, as before

    template<typename F, typename... Args>
    std::future<void> post(F f, Args&&... args)
    {
    Task task(std::bind<void>(f, std::forward<Args>(args)...));
    auto fut = task.get_future();
    std::lock_guard<std::mutex> lock(m_mutex);
    m_tasks.push(std::move(task));
    return fut;
    }

    private:
    void drawThread();
    std::mutex m_mutex;
    using Task = std::packaged_task<void()>;
    std::queue<Task> m_tasks;
    std::thread m_thread;
    };

    void WorkerThread::drawThread()
    {
    Task task;
    while(true)
    {
    {
    std::lock_guard<std::mutex> lock(m_mutex);
    task = std::move(m_tasks.front());
    m_tasks.pop();
    }
    task(); // run the task
    }
    }


    When the task is run any exceptions will be caught, stored in an exception_ptr and held until the result is read through the associated future.



    // other thread:

    auto fut = workerThread.post(&someDrawingFunc, arg1, arg2);
    ...
    // check future for errors
    try {
    fut.get();
    } catch (const std::exception& e) {
    // handle it
    }


    The producer thread could store the future objects in a queue when posting work to the consumer, and some other piece of code could check each future in the queue to see if it's ready and call get() to handle any exception.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 13 '14 at 11:19

























    answered Aug 13 '14 at 10:16









    Jonathan Wakely

    129k16238401




    129k16238401








    • 1




      +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
      – ComicSansMS
      Aug 13 '14 at 11:21










    • In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
      – ikh
      Aug 13 '14 at 11:22










    • @Jonathan Wakely Any special reason you use lock_guard in your example?
      – Michael IV
      Aug 13 '14 at 11:23










    • @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
      – Jonathan Wakely
      Aug 13 '14 at 11:23












    • @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
      – Jonathan Wakely
      Aug 13 '14 at 11:25
















    • 1




      +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
      – ComicSansMS
      Aug 13 '14 at 11:21










    • In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
      – ikh
      Aug 13 '14 at 11:22










    • @Jonathan Wakely Any special reason you use lock_guard in your example?
      – Michael IV
      Aug 13 '14 at 11:23










    • @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
      – Jonathan Wakely
      Aug 13 '14 at 11:23












    • @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
      – Jonathan Wakely
      Aug 13 '14 at 11:25










    1




    1




    +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
    – ComicSansMS
    Aug 13 '14 at 11:21




    +1 for packaged_task. People jump to bare std::thread far too quickly, when for many purposes it is actually too low-level.
    – ComicSansMS
    Aug 13 '14 at 11:21












    In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
    – ikh
    Aug 13 '14 at 11:22




    In this way, posting is required to catch the exceptions, isn't it? zz.. Btw, I think this approach is very similar to boost::asio::io_service::work
    – ikh
    Aug 13 '14 at 11:22












    @Jonathan Wakely Any special reason you use lock_guard in your example?
    – Michael IV
    Aug 13 '14 at 11:23




    @Jonathan Wakely Any special reason you use lock_guard in your example?
    – Michael IV
    Aug 13 '14 at 11:23












    @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
    – Jonathan Wakely
    Aug 13 '14 at 11:23






    @ikh, no, calling post can only throw an exception if memory allocation fails while creating the packaged_task or adding it to the queue. The task is run in the drawThread, so any exception happens there and is caught by the packaged_task and stored in the future.
    – Jonathan Wakely
    Aug 13 '14 at 11:23














    @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
    – Jonathan Wakely
    Aug 13 '14 at 11:25






    @MichaelIV, any reason you used unique_lock? Do you need to defer the lock? Or release it early? Or move it to another object? If not, why use the more complicated lock type? lock_guard just locks and unlocks, nothing more, and that's all the code requires.
    – Jonathan Wakely
    Aug 13 '14 at 11:25















    4














    Those answer suggest you to send exception_ptr to main thread manually. That's not bad way, but I suggest you another way: std::promise / boost::promise.



    (Since I don't have boost in this computer now, so I'll go with std::promise. However, there may be no big difference with boost.)



    Look the example code:



    #include <iostream>
    #include <exception>
    #include <thread>
    #include <future>
    #include <chrono>

    void foo()
    {
    throw "mission failure >o<";
    }

    int main()
    {
    std::promise<void> prm;

    std::thread thrd([&prm] {
    try
    {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    foo();
    prm.set_value();
    }
    catch (...)
    {
    prm.set_exception(std::current_exception());
    }
    });

    std::future<void> fu = prm.get_future();
    for (int i = 0; ; i++)
    {
    if (fu.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
    break;
    std::cout << "waiting ... [" << i << "]n";
    }

    try
    {
    fu.get();
    std::cout << "mission complete!n";
    }
    catch (const char *msg)
    {
    std::cerr << "exception: " << msg << "n";
    }

    thrd.join(); /* sorry for my compiler's absence of std::promise::set_value_at_thread_exit */
    }


    The benefit of this way is 1. you don't have to manage exceptions manually - std::promise and std::future will do everything and 2. you can use all feature around std::future. In this case, I'm doing other things (outputing waiting... message) while waiting the thread exit, through std::future::wait_for.






    share|improve this answer



















    • 1




      The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
      – Jonathan Wakely
      Aug 13 '14 at 10:52








    • 1




      The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
      – Jonathan Wakely
      Aug 13 '14 at 10:56










    • @JonathanWakely packaged_task?? I can't understand.. could you explain more?
      – ikh
      Aug 13 '14 at 11:08










    • I added another example to my answer, using packaged_task
      – Jonathan Wakely
      Aug 13 '14 at 11:14
















    4














    Those answer suggest you to send exception_ptr to main thread manually. That's not bad way, but I suggest you another way: std::promise / boost::promise.



    (Since I don't have boost in this computer now, so I'll go with std::promise. However, there may be no big difference with boost.)



    Look the example code:



    #include <iostream>
    #include <exception>
    #include <thread>
    #include <future>
    #include <chrono>

    void foo()
    {
    throw "mission failure >o<";
    }

    int main()
    {
    std::promise<void> prm;

    std::thread thrd([&prm] {
    try
    {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    foo();
    prm.set_value();
    }
    catch (...)
    {
    prm.set_exception(std::current_exception());
    }
    });

    std::future<void> fu = prm.get_future();
    for (int i = 0; ; i++)
    {
    if (fu.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
    break;
    std::cout << "waiting ... [" << i << "]n";
    }

    try
    {
    fu.get();
    std::cout << "mission complete!n";
    }
    catch (const char *msg)
    {
    std::cerr << "exception: " << msg << "n";
    }

    thrd.join(); /* sorry for my compiler's absence of std::promise::set_value_at_thread_exit */
    }


    The benefit of this way is 1. you don't have to manage exceptions manually - std::promise and std::future will do everything and 2. you can use all feature around std::future. In this case, I'm doing other things (outputing waiting... message) while waiting the thread exit, through std::future::wait_for.






    share|improve this answer



















    • 1




      The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
      – Jonathan Wakely
      Aug 13 '14 at 10:52








    • 1




      The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
      – Jonathan Wakely
      Aug 13 '14 at 10:56










    • @JonathanWakely packaged_task?? I can't understand.. could you explain more?
      – ikh
      Aug 13 '14 at 11:08










    • I added another example to my answer, using packaged_task
      – Jonathan Wakely
      Aug 13 '14 at 11:14














    4












    4








    4






    Those answer suggest you to send exception_ptr to main thread manually. That's not bad way, but I suggest you another way: std::promise / boost::promise.



    (Since I don't have boost in this computer now, so I'll go with std::promise. However, there may be no big difference with boost.)



    Look the example code:



    #include <iostream>
    #include <exception>
    #include <thread>
    #include <future>
    #include <chrono>

    void foo()
    {
    throw "mission failure >o<";
    }

    int main()
    {
    std::promise<void> prm;

    std::thread thrd([&prm] {
    try
    {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    foo();
    prm.set_value();
    }
    catch (...)
    {
    prm.set_exception(std::current_exception());
    }
    });

    std::future<void> fu = prm.get_future();
    for (int i = 0; ; i++)
    {
    if (fu.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
    break;
    std::cout << "waiting ... [" << i << "]n";
    }

    try
    {
    fu.get();
    std::cout << "mission complete!n";
    }
    catch (const char *msg)
    {
    std::cerr << "exception: " << msg << "n";
    }

    thrd.join(); /* sorry for my compiler's absence of std::promise::set_value_at_thread_exit */
    }


    The benefit of this way is 1. you don't have to manage exceptions manually - std::promise and std::future will do everything and 2. you can use all feature around std::future. In this case, I'm doing other things (outputing waiting... message) while waiting the thread exit, through std::future::wait_for.






    share|improve this answer














    Those answer suggest you to send exception_ptr to main thread manually. That's not bad way, but I suggest you another way: std::promise / boost::promise.



    (Since I don't have boost in this computer now, so I'll go with std::promise. However, there may be no big difference with boost.)



    Look the example code:



    #include <iostream>
    #include <exception>
    #include <thread>
    #include <future>
    #include <chrono>

    void foo()
    {
    throw "mission failure >o<";
    }

    int main()
    {
    std::promise<void> prm;

    std::thread thrd([&prm] {
    try
    {
    std::this_thread::sleep_for(std::chrono::seconds(5));
    foo();
    prm.set_value();
    }
    catch (...)
    {
    prm.set_exception(std::current_exception());
    }
    });

    std::future<void> fu = prm.get_future();
    for (int i = 0; ; i++)
    {
    if (fu.wait_for(std::chrono::seconds(1)) != std::future_status::timeout)
    break;
    std::cout << "waiting ... [" << i << "]n";
    }

    try
    {
    fu.get();
    std::cout << "mission complete!n";
    }
    catch (const char *msg)
    {
    std::cerr << "exception: " << msg << "n";
    }

    thrd.join(); /* sorry for my compiler's absence of std::promise::set_value_at_thread_exit */
    }


    The benefit of this way is 1. you don't have to manage exceptions manually - std::promise and std::future will do everything and 2. you can use all feature around std::future. In this case, I'm doing other things (outputing waiting... message) while waiting the thread exit, through std::future::wait_for.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 13 '14 at 10:51

























    answered Aug 13 '14 at 10:41









    ikh

    6,37311853




    6,37311853








    • 1




      The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
      – Jonathan Wakely
      Aug 13 '14 at 10:52








    • 1




      The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
      – Jonathan Wakely
      Aug 13 '14 at 10:56










    • @JonathanWakely packaged_task?? I can't understand.. could you explain more?
      – ikh
      Aug 13 '14 at 11:08










    • I added another example to my answer, using packaged_task
      – Jonathan Wakely
      Aug 13 '14 at 11:14














    • 1




      The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
      – Jonathan Wakely
      Aug 13 '14 at 10:52








    • 1




      The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
      – Jonathan Wakely
      Aug 13 '14 at 10:56










    • @JonathanWakely packaged_task?? I can't understand.. could you explain more?
      – ikh
      Aug 13 '14 at 11:08










    • I added another example to my answer, using packaged_task
      – Jonathan Wakely
      Aug 13 '14 at 11:14








    1




    1




    The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
    – Jonathan Wakely
    Aug 13 '14 at 10:52






    The problem with promise is you can only use it once, the question shows catching exceptions in a loop, implying it needs to keep handling exceptions after the first
    – Jonathan Wakely
    Aug 13 '14 at 10:52






    1




    1




    The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
    – Jonathan Wakely
    Aug 13 '14 at 10:56




    The way to do it with future would be for the producer to pass work to the consumer in the form of std::packaged_task objects, keeping hold of a future that shares state with each packaged_task. That way for every task posteed to the consumer there is a corresponding future, and a channel for getting the exception back
    – Jonathan Wakely
    Aug 13 '14 at 10:56












    @JonathanWakely packaged_task?? I can't understand.. could you explain more?
    – ikh
    Aug 13 '14 at 11:08




    @JonathanWakely packaged_task?? I can't understand.. could you explain more?
    – ikh
    Aug 13 '14 at 11:08












    I added another example to my answer, using packaged_task
    – Jonathan Wakely
    Aug 13 '14 at 11:14




    I added another example to my answer, using packaged_task
    – Jonathan Wakely
    Aug 13 '14 at 11:14











    1














    In the worker thread, you can catch the exception, and then retrieve a std::exception_ptr using std::current_exception. You can then store this somewhere, pick it up in the main thread, and throw it with std::rethrow_exception.






    share|improve this answer





















    • can you elaborate on how it is actually done?
      – Michael IV
      Aug 13 '14 at 9:28










    • What do you mean?
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:28










    • I mean that what you said I have already read in several places but none really explains how to do it.
      – Michael IV
      Aug 13 '14 at 9:29










    • What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:31






    • 1




      The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
      – Jonathan Wakely
      Aug 13 '14 at 10:05


















    1














    In the worker thread, you can catch the exception, and then retrieve a std::exception_ptr using std::current_exception. You can then store this somewhere, pick it up in the main thread, and throw it with std::rethrow_exception.






    share|improve this answer





















    • can you elaborate on how it is actually done?
      – Michael IV
      Aug 13 '14 at 9:28










    • What do you mean?
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:28










    • I mean that what you said I have already read in several places but none really explains how to do it.
      – Michael IV
      Aug 13 '14 at 9:29










    • What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:31






    • 1




      The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
      – Jonathan Wakely
      Aug 13 '14 at 10:05
















    1












    1








    1






    In the worker thread, you can catch the exception, and then retrieve a std::exception_ptr using std::current_exception. You can then store this somewhere, pick it up in the main thread, and throw it with std::rethrow_exception.






    share|improve this answer












    In the worker thread, you can catch the exception, and then retrieve a std::exception_ptr using std::current_exception. You can then store this somewhere, pick it up in the main thread, and throw it with std::rethrow_exception.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Aug 13 '14 at 9:27









    Robert Allan Hennigan Leahy

    5,0102041




    5,0102041












    • can you elaborate on how it is actually done?
      – Michael IV
      Aug 13 '14 at 9:28










    • What do you mean?
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:28










    • I mean that what you said I have already read in several places but none really explains how to do it.
      – Michael IV
      Aug 13 '14 at 9:29










    • What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:31






    • 1




      The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
      – Jonathan Wakely
      Aug 13 '14 at 10:05




















    • can you elaborate on how it is actually done?
      – Michael IV
      Aug 13 '14 at 9:28










    • What do you mean?
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:28










    • I mean that what you said I have already read in several places but none really explains how to do it.
      – Michael IV
      Aug 13 '14 at 9:29










    • What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
      – Robert Allan Hennigan Leahy
      Aug 13 '14 at 9:31






    • 1




      The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
      – Jonathan Wakely
      Aug 13 '14 at 10:05


















    can you elaborate on how it is actually done?
    – Michael IV
    Aug 13 '14 at 9:28




    can you elaborate on how it is actually done?
    – Michael IV
    Aug 13 '14 at 9:28












    What do you mean?
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:28




    What do you mean?
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:28












    I mean that what you said I have already read in several places but none really explains how to do it.
    – Michael IV
    Aug 13 '14 at 9:29




    I mean that what you said I have already read in several places but none really explains how to do it.
    – Michael IV
    Aug 13 '14 at 9:29












    What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:31




    What do you mean "how to do it"? You get a std::exception_ptr, pass it off to the main thread, and then rethrow it.
    – Robert Allan Hennigan Leahy
    Aug 13 '14 at 9:31




    1




    1




    The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
    – Jonathan Wakely
    Aug 13 '14 at 10:05






    The same way you pass any object from one thread to another. There are various options, which is best depends on your requirements. A std::queue<std::exception_ptr> guarded by a mutex would be one way.
    – Jonathan Wakely
    Aug 13 '14 at 10:05













    1














    Exceptions are synchronous. Which means there is no way to pass them between threads as exceptions. You cannot tell to any old thread "stop whatever you are doing and handle this". (Well you can if you deliver a POSIX signal to it, but that's not quite a C++ exception).



    You can of course always pass an object with the exception data (as opposed to the state of being in an exception-handling mode) to another thread in the same way you would pass any other data between threads. A concurrent queue will do. Then you process it in the target thread. The target thread should be actively reading data from the queue.






    share|improve this answer




























      1














      Exceptions are synchronous. Which means there is no way to pass them between threads as exceptions. You cannot tell to any old thread "stop whatever you are doing and handle this". (Well you can if you deliver a POSIX signal to it, but that's not quite a C++ exception).



      You can of course always pass an object with the exception data (as opposed to the state of being in an exception-handling mode) to another thread in the same way you would pass any other data between threads. A concurrent queue will do. Then you process it in the target thread. The target thread should be actively reading data from the queue.






      share|improve this answer


























        1












        1








        1






        Exceptions are synchronous. Which means there is no way to pass them between threads as exceptions. You cannot tell to any old thread "stop whatever you are doing and handle this". (Well you can if you deliver a POSIX signal to it, but that's not quite a C++ exception).



        You can of course always pass an object with the exception data (as opposed to the state of being in an exception-handling mode) to another thread in the same way you would pass any other data between threads. A concurrent queue will do. Then you process it in the target thread. The target thread should be actively reading data from the queue.






        share|improve this answer














        Exceptions are synchronous. Which means there is no way to pass them between threads as exceptions. You cannot tell to any old thread "stop whatever you are doing and handle this". (Well you can if you deliver a POSIX signal to it, but that's not quite a C++ exception).



        You can of course always pass an object with the exception data (as opposed to the state of being in an exception-handling mode) to another thread in the same way you would pass any other data between threads. A concurrent queue will do. Then you process it in the target thread. The target thread should be actively reading data from the queue.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        answered Aug 13 '14 at 9:51


























        community wiki





        n.m.































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f25282620%2fcatching-exception-from-worker-thread-in-the-main-thread%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            404 Error Contact Form 7 ajax form submitting

            How to know if a Active Directory user can login interactively

            TypeError: fit_transform() missing 1 required positional argument: 'X'