Results 1 to 11 of 11

Thread: using QtConcurrent::run to run same function multiple time simultaniously

  1. #1
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default using QtConcurrent::run to run same function multiple time simultaniously

    Good day All

    I have this issue, that I want to make sure how to solve it

    I use QtConcurrent::run to run a function in the background.

    This function is run multiple times (it takes a while to complete executing, it saves image to network drive and then updates the database), and the next call to this function can be issued while the first call is still executing.
    I also pass a database object to this function. I want to know if this is a correct thing to do or not. the problem is that it used to run OK under Windows, but under Linux, it keeps crashing whenever the next call to this function is issued.

    here is my code
    Qt Code:
    1. QFuture<bool> future = QtConcurrent::run(&saveImages, imagesList, db);
    2. saveImagesWatcher.setFuture(future);
    To copy to clipboard, switch view to plain text mode 

    This is the saveImages function, its a static function
    Qt Code:
    1. bool MainWindow::saveImages(QList<QImage> &list, QSqlDatabase &database)
    2. {
    3. QString path = /path/to/drive
    4.  
    5. QDir dir;
    6.  
    7. if( !dir.exists(path) )
    8. if( !dir.mkpath(path) )
    9. return false;
    10.  
    11. bool ret = true;
    12. int i = 0;
    13. int id_article = 10; //set up somewhere else
    14.  
    15. for(i=0; i< list.count(); i++) //this could take a lof of time. depending on the images number
    16. {
    17. QString fname = QString("%1-%2.jpg").arg(id_article).arg(i+1);
    18. if( file.exists(path + fname) )
    19. file.remove(path + fname);
    20.  
    21. ret = list[i].save(path + fname, "jpg", 100);
    22. if(!ret)
    23. {
    24. qDebug() << "saveImages(): Saving image " << fname << " Unsuccessfull";
    25. ret = false;
    26. break;
    27. }
    28. }
    29.  
    30. if(!ret)
    31. {
    32. deleteEntry(database, id_article);
    33. return false;
    34. }
    35.  
    36. qDebug("saveImages(): Everything is OK for article %d, updating the status and images number", id_article);
    37. updateStatus(database, id_article, 2);
    38. updateImagesNumber(database, id_article, list.count());
    39. return true;
    40. }
    To copy to clipboard, switch view to plain text mode 

    I want to know what is the best way to run my function in a multiple threads. and should I pass the database object to it or not. if I should use QThread, how can I make multiple calls to the same function, i.e. how can I create multiple thread objects (they should be created every time the function gets called) and run them.

    Best regards

  2. #2
    Join Date
    Jul 2009
    Posts
    139
    Thanks
    13
    Thanked 59 Times in 52 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    The documentations says:
    A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported.

    In addition, the third party libraries used by the QSqlDrivers can impose further restrictions on using the SQL Module in a multithreaded program. Consult the manual of your database client for more information
    Depending on the database driver used, you should be right just creating a new connection in each thread. Otherwise, you could use signals and slots to make sure the database operations are always run in the same thread.

  3. #3
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    Thanks for the reply.

    I would like to know also if the running the function more than one time concurrently (even if we dont have SQL) is correct or not.
    i.e. saveImages function called for the next time, while the previous call to the saveImages has not yet ended.

    regards

  4. #4
    Join Date
    Jul 2007
    Location
    Jundiai/SP, Brazil
    Posts
    114
    Thanks
    5
    Thanked 7 Times in 6 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    Hi,

    I think you should try to use QtConcurrent::mapped to do this.
    This approach seems much more applicable to your case
    than using QtConcurrent::run()

    Take a look at the documentation QtAssistant.

    Qt Code:
    1. QFuture<QImage> result = QtConcurrent::mapped(files, procImages);
    2. images->setFuture(result);
    To copy to clipboard, switch view to plain text mode 

  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: using QtConcurrent::run to run same function multiple time simultaniously

    Quote Originally Posted by yazwas View Post
    I would like to know also if the running the function more than one time concurrently (even if we dont have SQL) is correct or not.
    If the function is reentrant (i.e. uses no global or static data) then yes. But in this particular situation I would probably use mapped() as suggested. The only problem would be if you tried to save the same file more than once at the same time. But with run() you have the exact same situation. Also watch out for the id_article variable if you intend to modify it somewhere (it can make your function not reentrant).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  6. #6
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    Thank you all for the reply.

    I have another question, if I want to still use the same function, but I would like to use Mutex, like the following case

    Qt Code:
    1. //GLOBAL definition
    2. QMutex mutex;
    To copy to clipboard, switch view to plain text mode 

    Qt Code:
    1. bool MainWindow::saveImages(QList<QImage> &list, int id_article)
    2. {
    3. mutex.lock();
    4. QString path = /path/to/drive
    5.  
    6. QDir dir;
    7.  
    8. if( !dir.exists(path) )
    9. if( !dir.mkpath(path) )
    10. {
    11. mutex.unlock();
    12. return false;
    13. }
    14.  
    15. bool ret = true;
    16. int i = 0;
    17.  
    18. for(i=0; i< list.count(); i++) //this could take a lof of time. depending on the images number
    19. {
    20. QString fname = QString("%1-%2.jpg").arg(id_article).arg(i+1);
    21. if( file.exists(path + fname) )
    22. file.remove(path + fname);
    23.  
    24. ret = list[i].save(path + fname, "jpg", 100);
    25. if(!ret)
    26. {
    27. qDebug() << "saveImages(): Saving image " << fname << " Unsuccessfull";
    28. ret = false;
    29. break;
    30. }
    31. }
    32.  
    33. mutex.unlock();
    34. return ret;
    35. }
    To copy to clipboard, switch view to plain text mode 

    here I removed all the static code, but I added the mutex variable (global one).

    if I run this code
    Qt Code:
    1. QFuture<bool> future_1 = QtConcurrent::run(&saveImages, list_1, id_1); //list_1 is 100's images, and it can take a few minutes
    2. saveImagesWatcher.setFuture(future_1);
    3.  
    4. .... do some work to get list_2, and id_2
    5.  
    6. QFuture<bool> future_2 = QtConcurrent::run(&saveImages, list_2, id_2);//list_2 is a couple of images and it will take a few seconds
    7. saveImagesWatcher.setFuture(future_2);
    To copy to clipboard, switch view to plain text mode 

    This make the program save the images in list 1 before saving the images in list 2, right?
    Is this a good way to enforce locking of the function? and ensure serialization access to the saveImages function?

    Thanks a lot
    Last edited by yazwas; 2nd June 2010 at 22:09.

  7. #7
    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: using QtConcurrent::run to run same function multiple time simultaniously

    If you use a mutex in such way then you have no concurrency at all. I don't see the point of running the method several times this way.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  8. #8
    Join Date
    Jul 2009
    Location
    Jordan, and UAE
    Posts
    55
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    Quote Originally Posted by wysota View Post
    If you use a mutex in such way then you have no concurrency at all. I don't see the point of running the method several times this way.
    The reason for this is that the user do a generate operation that creates a list of images and then I save those images, I used to do the saving operation them in foreground, and that worked OK, but it took too much time and the program just hangs!

    The solution was to move the save operation to background. I use QtConcurrent::run() to do that

    Now when it runs in background, the user can do generate operations a few times while the images of the first operation has not finished saving

    What I really want to do, is make the function save the images of the 2nd generate operation AFTER the completion of saving for the images of the first operation.
    saving of images from the 3rd generation after saving of images from 2nd operation and so on.

    I hope this makes sense why I'm asking about Mutex and using it as in the code above, and if that can do this for me.

    Best regards

  9. #9
    Join Date
    Jan 2006
    Location
    Earth (Terra)
    Posts
    87
    Thanks
    4
    Thanked 6 Times in 4 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows Symbian S60

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    Seems like you could do this with just a worker thread running in the background, saving the images in a loop. In which case, you don't need mutexes at all and you only need one extra thread. If you want to allow the user to do successive saves, but you want the previous one to complete, push them onto a queue and run them serially (might be easier with QThread objects that you can push onto the queue.)

    Still don't need mutexes.

  10. #10
    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: using QtConcurrent::run to run same function multiple time simultaniously

    I suggest you read this article: [wiki=Keeping_the_GUI_Responsive]Keeping the GUI Responsive[/wiki], there are different approaches you can take described there.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  11. The following user says thank you to wysota for this useful post:

    soulless (4th June 2010)

  12. #11
    Join Date
    Jul 2009
    Posts
    139
    Thanks
    13
    Thanked 59 Times in 52 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11

    Default Re: using QtConcurrent::run to run same function multiple time simultaniously

    It might be worth noting that Qt's signals and slots provide a nice thread safe queueing mechanism. If you use your own queue, you have to be careful about serialising access to the queue object (ie. you don't want to be pushing and popping at exactly the same instance).

Similar Threads

  1. Replies: 7
    Last Post: 10th May 2010, 11:26
  2. add multiple rows at a time in tablewidgets
    By rk0747 in forum Qt Programming
    Replies: 0
    Last Post: 15th April 2010, 06:54
  3. Replies: 0
    Last Post: 7th August 2009, 19:21
  4. Replies: 1
    Last Post: 24th November 2008, 12:02
  5. Replies: 1
    Last Post: 1st February 2008, 18:55

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.