Results 1 to 6 of 6

Thread: throwing exceptions across thread boundaries (using QtConcurrent)

  1. #1
    Join Date
    Jan 2006
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default throwing exceptions across thread boundaries (using QtConcurrent)

    Hello,

    I need to throw an exception across a thread boundary.
    I thought this was possible with QtConcurrent::Exception after reading the docs (http://doc.trolltech.com/4.4/qtconcu...exception.html) however this does not seem to work for me. I tested the following code with gcc 4.3 and with VS2008:

    Qt Code:
    1. #include <QtCore>
    2.  
    3. class MyException : public QtConcurrent::Exception
    4. {
    5. public:
    6. void raise() const { throw *this; }
    7. Exception *clone() const { return new MyException(*this); }
    8. };
    9.  
    10. void runInOtherThread()
    11. {
    12. qDebug("other thread");
    13. throw MyException();
    14. }
    15.  
    16. int main(int argc, char* argv[])
    17. {
    18. QCoreApplication a(argc, argv);
    19. try
    20. {
    21. QtConcurrent::run(&runInOtherThread);
    22. }
    23. catch(MyException &e)
    24. {
    25. qDebug("exception caught");
    26. }
    27. return a.exec();
    28. }
    To copy to clipboard, switch view to plain text mode 

    I would expect to end up in the catch block in the main() function. However i get the following output:
    Qt Code:
    1. $ ./exceptiontest
    2. other thread
    3. Qt Concurrent has caught an exception thrown from a worker thread.
    4. This is not supported, exceptions thrown in worker threads must be
    5. caught before control returns to Qt Concurrent.
    6. terminate called after throwing an instance of 'MyException'
    7. what(): std::exception
    8. Aborted
    9. $
    To copy to clipboard, switch view to plain text mode 

    The warning is printed in QThreadPoolThread::run().
    This conflicts with my interpretation of the manual, which says:
    Qt Code:
    1. Qt Concurrent supports throwing and catching exceptions across thread boundaries, provided that the exception inherit from QtConcurrent::Exception and implement two helper functions:
    To copy to clipboard, switch view to plain text mode 

    But probably i'm just doing something wrong here
    Any help or pointers would be very much appreciated

    thanks,
    glenn

  2. #2
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: throwing exceptions across thread boundaries (using QtConcurrent)

    Strictly from the logical point of view catching C++ exceptions in threads different than the ones they originate from wouldn't make sense. I'm not sure if it would make sense even with Java exceptions...

    You have two different flows which may be at arbitrary points during the exception and you want one of them (the outer one) to jump completely elsewhere (to the "catch" block) and then what? go back? Continue after the catch block?

    run() is an asynchronous call - the calling thread continues execution. From what I see it is only possible to catch transferred exceptions thrown by the four methods mentioned at the end of the reference section you mention when using QFuture (and run() uses one). Other exceptions won't be caught properly. So either use a blocking call or don't use exceptions (but signals and slots or events, for example).

  3. #3
    Join Date
    Oct 2006
    Posts
    279
    Thanks
    6
    Thanked 40 Times in 39 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: throwing exceptions across thread boundaries (using QtConcurrent)

    I guess the documentaion could be a bit clearer. In the following scenario, the exception gets caught as expected:
    Qt Code:
    1. void runInOtherThread(int)
    2. {
    3. qDebug("other thread");
    4. throw MyException();
    5. }
    6.  
    7. int main(int argc, char* argv[])
    8. {
    9. QCoreApplication a(argc, argv);
    10. try
    11. {
    12. QVector<int> argument(100);
    13. QtConcurrent::map(argument, &runInOtherThread).waitForFinished();
    14. }
    15. catch(MyException &e)
    To copy to clipboard, switch view to plain text mode 
    So if you have a scenario where you have a lot of jobs to be executed asynchronously while the main thread waits, it would make sense to throw an exception to cancel all processing on failure.
    But Wysota is right, it only makes sense when using a blocking call. In your example, the main thread would most likely have left the try-catch block before the worker thread gets around to throwing the exception.

  4. #4
    Join Date
    Jan 2006
    Posts
    3
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11

    Default Re: throwing exceptions across thread boundaries (using QtConcurrent)

    Thanks for your responses.
    I can now see that the code i posted can indeed not work as is.
    However shouldn't i be able to catch the exception when i use a QFuture with the QtConcurrent::run() and call future.result() in a slot connected to QFutureWatcher::finished() ?

    I tried to do this but it does not work either..

  5. #5
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,359
    Thanks
    3
    Thanked 5,015 Times in 4,792 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: throwing exceptions across thread boundaries (using QtConcurrent)

    No, because it has no way of knowing you are calling it from a slot connected to finished. And even if it did, it still wouldn't make sense to thow an exception there, result() is only a getter and nothing bad can happen after finished() is signalled as there are no more threads performing the job.

  6. #6
    Join Date
    Sep 2011
    Posts
    1
    Qt products
    Qt3 Qt4
    Platforms
    Unix/X11 Windows

    Default Re: throwing exceptions across thread boundaries (using QtConcurrent)

    I have a similar problem with the following piece of code (Manager :: processPlugins is a valid method that receives 3 ints as parameters; the piece of code is inside a method that belongs to a Manager instance)

    1. QList<QFuture<void> > workers;
    2. int numWorkers = QThread::idealThreadCount();
    3. for( int worker = 0; worker < numWorkers; worker++ ){
    4. workers.push_back( QtConcurrent::run(
    5. this,
    6. &Manager :: processPlugins,
    7. worker,
    8. 2,
    9. 3);
    10. }
    11. for( int worker = 0; worker < workers.size(); worker++ ) {
    12. try {
    13. workers[worker].waitForFinished();
    14. } catch ( MyException& ex ) {
    15. printf( "Exception thrown\n" );
    16. }
    17. }


    However, when a MyException instance is thrown inside processPlugins, the catch block does not execute. Instead, the application terminates, and this warning appears:

    Qt Concurrent has caught an exception thrown from a worker thread.
    This is not supported, exceptions thrown in worker threads must be
    caught before control returns to Qt Concurrent

    Am I missing something?
    Thanks for any help

    Cheers,
    João Magalhães

Similar Threads

  1. KDE/QWT doubt on debian sarge
    By hildebrand in forum KDE Forum
    Replies: 13
    Last Post: 25th April 2007, 06:13
  2. Replies: 10
    Last Post: 20th March 2007, 22:19

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.