Results 1 to 12 of 12

Thread: Catching exceptions that were thrown by a concurrent thread

  1. #1
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Catching exceptions that were thrown by a concurrent thread

    I have a problem similar to this poster, but I can't figure out what I should do in my case. Instead of calling exit(EXIT_FAILURE) on a separate thread, I want the main thread to handle the exception. To me this looks clean and organized. I tried this:

    Qt Code:
    1. #include <QString>
    2. #include <iostream>
    3. #include <QtConcurrentRun>
    4. #include <qtconcurrentexception.h>
    5. using std::cerr;
    6. using std::ostream;
    7.  
    8. class MyException : public QtConcurrent::Exception {
    9. public:
    10. MyException(const QString& msg) { _msg = msg; }
    11. virtual ~MyException() throw() {}
    12.  
    13. const QString& msg() { return _msg; }
    14.  
    15. void raise() const { throw *this; }
    16. Exception *clone() const { return new MyException(*this); }
    17. private:
    18. QString _msg;
    19. };
    20.  
    21. void separateThread() {
    22. int i = 0;
    23. while (i < 10000)
    24. ++i;
    25.  
    26. throw MyException("This exception should be caught by the main thread");
    27. }
    28.  
    29. int main() {
    30. QFuture<void> otherThread = QtConcurrent::run(&separateThread);
    31.  
    32. int i = 0;
    33. while (i < 10)
    34. ++i;
    35.  
    36. try {
    37. otherThread.waitForFinished();
    38. } catch (MyException& e) {
    39. std::cerr << "QUITTING WITH ERROR\n" << e.msg().toStdString() << std::endl;
    40. }
    41.  
    42. return 0;
    43. }
    To copy to clipboard, switch view to plain text mode 

    I kept in mind that

    When using QFuture, transferred exceptions will be thrown when calling the following functions:
    - QFuture::waitForFinished()
    - QFuture::result()
    - QFuture::resultAt()
    - QFuture::results()
    The exception, however, isn't handled and the program crashes. What am I doing wrong here?

  2. #2
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    It might be thrown when you call QtConcurrent::run.

    get rid of the pointless while i < 10 loop, and put the run(...) command inside the try block. Does it help?

    edit: nope, just tried it. hmmm....


    Added after 16 minutes:


    I note that refactoring to use blockingMap does work as expected.

    I saw this:
    Note that the QFuture returned by QtConcurrent::run() does not support canceling, pausing, or progress reporting. The QFuture returned can only be used to query for the running/finished status and the return value of the function.
    So I presume there is something slightly different about QtConcurrent::run(...) that means you can't use run for your desired behaviour.

    I haven't tried, but I bet map(...) and .waitForFinished(...) would work - you just need to make a dummy sequence
    Last edited by amleto; 22nd December 2011 at 18:22.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  3. #3
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    I managed to replicate the desired behavior by connecting a signal from the other thread to a slot that executes on the main thread, where the exception is thrown and caught.

  4. #4
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    But what is the point in using concurrent to start a slot running in the main thread
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  5. #5
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    I'm not delegating the work to the main thread. When I want to throw an exception on the other thread, I broadcast a signal that is connect with a private slot on the main thread. This private slot throws the exception. But I claimed victory too soon.

    Qt has caught an exception thrown from an event handler. Throwing
    exceptions from an event handler is not supported in Qt. You must
    reimplement QApplication::notify() and catch all exceptions there.
    Am I searching in the right direction though? I don't see why using QtConcurrent::map with a dummy sequence (sounds kinda clumsy) would fix the issue.

  6. #6
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    You don't see why? Even though I told you that blockingMap works fine?

    Qt Code:
    1. #include <QString>
    2.  
    3. #include <iostream>
    4. #include <vector>
    5.  
    6. #include <QtCore>
    7.  
    8. using std::cerr;
    9. using std::ostream;
    10.  
    11. class MyException : public QtConcurrent::Exception {
    12.  
    13. public:
    14.  
    15. MyException(const QString& msg) { _msg = msg; }
    16. virtual ~MyException() throw() {}
    17.  
    18. const QString& msg() const { return _msg; }
    19. void raise() const { throw *this; }
    20. Exception *clone() const { return new MyException(*this); }
    21.  
    22. private:
    23. QString _msg;
    24. };
    25.  
    26.  
    27.  
    28. void separateThread(int) {
    29.  
    30. int i = 0;
    31. while (i < 10000)
    32. ++i;
    33.  
    34. throw MyException("This exception should be caught by the main thread");
    35. }
    36.  
    37.  
    38. int main()
    39. {
    40. std::vector<int> ints(1);
    41.  
    42. try
    43. {
    44. QtConcurrent::blockingMap(ints, separateThread);
    45. }
    46. catch (const MyException& e)
    47. {
    48. std::cerr << "QUITTING WITH ERROR\n" << e.msg().toStdString() << std::endl;
    49. }
    50.  
    51. return 0;
    52. }
    To copy to clipboard, switch view to plain text mode 
    Last edited by amleto; 23rd December 2011 at 17:27.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  7. #7
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    Note: This function will block until all items in the sequence have been processed.
    -- http://developer.qt.nokia.com/doc/qt...ml#blockingMap
    But if blockingMap blocks until the function is done executing for each item in the sequence, then the function isn't being executed in a separate thread while the main thread carries on its duties, is it?

  8. #8
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    Firstly, yes it IS in a separate thread. Secondly, where is that your requirement?? Your own example blocks with waitforfinished!!

    In any event, if you want asych behaviour then just use map. like I said already.
    Last edited by amleto; 26th December 2011 at 23:07.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  9. #9
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    Quote Originally Posted by amleto View Post
    Your own example blocks with waitforfinished!!
    At the end of my calculations on the main thread, I wait for the second thread to finish his calculations. In practice you could use two threads to do calculations that can be done in parallel. The main thread does his calculations while the second thread does his calculations as well, then the main thread waits for the second thread to finish working. The main thread then uses calculation results from both threads to make a final calculation.

    Why would I ever want to do work on a second thread and then exit without waiting for the results?

    Quote Originally Posted by amleto View Post
    Firstly, yes it IS in a separate thread. Secondly, where is that your requirement??
    It seems kinda pointless to do work on a separate thread while the main thread can't carry out any calculations itself. The whole point of multithreading is that you can execute calculations in parallel.

    Quote Originally Posted by amleto View Post
    In any event, if you want asych behaviour then just use map. like I said already.
    If I change blockingMap to map in your code, the program exits before the exception is thrown. That isn't very productive. This seems to work though:

    Qt Code:
    1. #include <QString>
    2. #include <QtConcurrentRun>
    3.  
    4. #include <iostream>
    5. #include <vector>
    6.  
    7. #include <QtCore>
    8.  
    9. using std::cerr;
    10. using std::ostream;
    11.  
    12. class MyException : public QtConcurrent::Exception {
    13.  
    14. public:
    15.  
    16. MyException(const QString& msg) { _msg = msg; }
    17. virtual ~MyException() throw() {}
    18.  
    19. const QString& msg() const { return _msg; }
    20. void raise() const { throw *this; }
    21. Exception *clone() const { return new MyException(*this); }
    22.  
    23. private:
    24. QString _msg;
    25. };
    26.  
    27.  
    28.  
    29. void separateThread(int) {
    30.  
    31. int i = 0;
    32. while (i < 10000)
    33. ++i;
    34.  
    35. throw MyException("This exception should be caught by the main thread");
    36. }
    37.  
    38.  
    39. int main()
    40. {
    41. std::vector<int> ints(1);
    42. QFuture<void> future;
    43.  
    44. try
    45. {
    46. future = QtConcurrent::map(ints, separateThread);
    47.  
    48. int i = 0;
    49. while (i < 10000)
    50. ++i;
    51.  
    52. future.waitForFinished();
    53. }
    54. catch (const MyException& e)
    55. {
    56. std::cerr << "QUITTING WITH ERROR\n" << e.msg().toStdString() << std::endl;
    57. }
    58.  
    59. return 0;
    60. }
    To copy to clipboard, switch view to plain text mode 

  10. #10
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    Quote Originally Posted by blooglet View Post
    At the end of my calculations on the main thread, I wait for the second thread to finish his calculations. In practice you could use two threads to do calculations that can be done in parallel. The main thread does his calculations while the second thread does his calculations as well, then the main thread waits for the second thread to finish working. The main thread then uses calculation results from both threads to make a final calculation.

    Why would I ever want to do work on a second thread and then exit without waiting for the results?


    It seems kinda pointless to do work on a separate thread while the main thread can't carry out any calculations itself. The whole point of multithreading is that you can execute calculations in parallel.



    If I change blockingMap to map in your code, the program exits before the exception is thrown. That isn't very productive. This seems to work though:
    I didn't say replace word for word. I said use map instead of blocking map. And your code uses exactly what I said to do in post #2!

    I don't see why using QtConcurrent::map with a dummy sequence (sounds kinda clumsy) would fix the issue.
    Can you see now?
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

  11. #11
    Join Date
    Nov 2010
    Posts
    77
    Thanks
    17
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    Quote Originally Posted by amleto View Post
    Can you see now?
    I've verified that it works, but since I have to supply a dummy sequence it looks like I'm using that function for a purpose it wasn't intended for.

  12. #12
    Join Date
    Sep 2011
    Posts
    1,241
    Thanks
    3
    Thanked 127 Times in 126 Posts
    Qt products
    Qt4
    Platforms
    Windows

    Default Re: Catching exceptions that were thrown by a concurrent thread

    you are welcome.
    If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar Threads

  1. Replies: 5
    Last Post: 6th September 2011, 23:19
  2. [QtJambi] No Exceptions thrown
    By dachick in forum Qt Programming
    Replies: 1
    Last Post: 14th November 2010, 13:04
  3. how to debugger Qt concurrent with GDB
    By learning_qt in forum Qt Programming
    Replies: 0
    Last Post: 8th November 2010, 12:13
  4. Catching exceptions with Qt
    By The_Fallen in forum Qt Programming
    Replies: 6
    Last Post: 30th July 2010, 19:39
  5. concurrent signals handling
    By s_stavrev in forum Qt Programming
    Replies: 2
    Last Post: 4th July 2010, 15:16

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.